File: bunits.sh
   1 #!/bin/sh
   2 
   3 # The MIT License (MIT)
   4 #
   5 # Copyright © 2026 pacman64
   6 #
   7 # Permission is hereby granted, free of charge, to any person obtaining a copy
   8 # of this software and associated documentation files (the “Software”), to deal
   9 # in the Software without restriction, including without limitation the rights
  10 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11 # copies of the Software, and to permit persons to whom the Software is
  12 # furnished to do so, subject to the following conditions:
  13 #
  14 # The above copyright notice and this permission notice shall be included in
  15 # all copies or substantial portions of the Software.
  16 #
  17 # THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  20 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  23 # SOFTWARE.
  24 
  25 
  26 # bunits [options...] [quantity/unit pairs...]
  27 #
  28 # Better UNITS is an easier way to use the `units` command-line app, with a
  29 # focus on shortcuts for converting into international units.
  30 #
  31 # Several unit shortcuts are available, including
  32 #
  33 #   ac, acre, acres
  34 #   cup, cups
  35 #   day, days
  36 #   deg, degs, degree, degrees
  37 #   f, fahr, fahren, fahrenheit, fahrenheits
  38 #   floz,
  39 #   ft, feet, foot, ft2, ft^2, sqft, sqfeet, ft3, ft^3, cuft, cufeet
  40 #   gal, gallon, gallons
  41 #   gb, gib, gibi, gibibytes
  42 #   hr, hour, hours
  43 #   in, inch, inches
  44 #   kb, kib, kibi, kibibytes
  45 #   lb, lbs, pound, pounds
  46 #   mb, mib, mibi, mibibytes
  47 #   mi, mile, miles, mi2, mi^2, miles^2, sqmi, sqmile, sqmiles
  48 #   mi3, mi^3, miles^3, cumi, cumile, cumiles
  49 #   min, minute, minutes
  50 #   mph
  51 #   nmi, nmile, nmiles, nmi2, nmi^2, nmile^2, nmiles^2
  52 #   oz, ozs, ounce, ounces
  53 #   pt, pts, pint, pints, uspint, uspints
  54 #   tb, tib, tibi, tibibytes
  55 #   yd, yds, yard, yards, yd2, yds2, yd^2, yds^2, yard^2, yards^2
  56 #   wk, week, weeks
  57 #
  58 # The options are, available both in single and double-dash versions
  59 #
  60 #   -h, -help    show this help message
  61 
  62 
  63 case "$1" in
  64     -h|--h|-help|--help)
  65         awk '/^# +bunits /, /^$/ { gsub(/^# ?/, ""); print }' "$0"
  66         exit 0
  67     ;;
  68 esac
  69 
  70 [ "$1" = '--' ] && shift
  71 
  72 if [ $# -lt 2 ]; then
  73     awk '/^# +bunits /, /^$/ { gsub(/^# ?/, ""); print }' "$0"
  74     exit 0
  75 fi
  76 
  77 conv="units -v -H ''"
  78 
  79 while [ $# -ge 2 ]; do
  80     # unit="$(echo "$2" | awk '{ print tolower($0) }')"
  81     unit="$(echo "$2" | tr '[A-Z]' '[a-z]')"
  82 
  83     case "${unit}" in
  84         ac|acre|acres) ${conv} "$1 acres" kilometers^2;;
  85         cup|cups) ${conv} "$1 cups" liters;;
  86         day|days) ${conv} "$1 days" seconds;;
  87         deg|degs|degree|degrees) ${conv} "$1 degrees" radians;;
  88         f|fahr|fahren|fahrenheit|fahrenheits) ${conv} "tempF($1)" tempC;;
  89         floz) ${conv} "$1 floz" milliliters;;
  90         ft|feet|foot) ${conv} "$1 feet" meters;;
  91         ft2|ft^2|sqft|sqfeet) ${conv} "$1 ft^2" meters^2;;
  92         ft3|ft^3|cuft|cufeet) ${conv} "$1 ft^3" meters^3;;
  93         gal|gallon|gals|gallons) ${conv} "$1 gallons" liters;;
  94         gb|gib|gibi|gibibytes) ${conv} "$1 gibibytes" bytes;;
  95         hr|hour|hours) ${conv} "$1 hours" seconds;;
  96         in|inch|inches) ${conv} "$1 inches" centimeters;;
  97         kb|kib|kibi|kibibytes) ${conv} "$1 kibibytes" bytes;;
  98         lb|lbs|pound|pounds) ${conv} "$1 pounds" kilograms;;
  99         mb|mib|mibi|mibibytes) ${conv} "$1 mibibytes" bytes;;
 100         mi|mile|miles) ${conv} "$1 miles" kilometers;;
 101         min|minute|minutes) ${conv} "$1 minutes" seconds;;
 102         mi2|mi^2|miles^2|sqmi|sqmile|sqmiles) ${conv} "$1 mi^2" kilometers^2;;
 103         mi3|mi^3|miles^3|cumi|cumile|cumiles) ${conv} "$1 mi^3" kilometers^3;;
 104         mph) ${conv} "$1 mph" kph;;
 105         nmi|nmile|nmiles) ${conv} "$1 nmi" kilometers;;
 106         nmi2|nmi^2|nmile^2|nmiles^2) ${conv} "$1 nmi^2" kilometers^2;;
 107         oz|ozs|ounce|ounces) ${conv} "$1 ounces" grams;;
 108         pt|pts|pint|pints|uspint|uspints) ${conv} "$1 uspints" liters;;
 109         tb|tib|tibi|tibibytes) ${conv} "$1 tibibytes" bytes;;
 110         yd|yds|yard|yards) ${conv} "$1 yards" meters;;
 111         yd2|yds2|yd^2|yds^2|yard^2|yards^2) ${conv} "$1 yards^2" meters^2;;
 112         wk|wks|week|weeks) ${conv} "$1 weeks" seconds;;
 113         *) printf "unsupported unit shortcut '%s'\n" "${unit}" >&2; exit 1;;
 114     esac
 115 
 116     shift
 117     shift
 118 done
 119 
 120 if [ $# -eq 1 ]; then
 121     printf "you forgot the unit for the last value\n" >&2
 122     exit 1
 123 fi