Fix bin() output and split(); add padding option.
This commit is contained in:
108
bash/base.sh
108
bash/base.sh
@@ -22,12 +22,12 @@ usage() {
|
|||||||
help() {
|
help() {
|
||||||
cat << _EOF
|
cat << _EOF
|
||||||
usage: $CMDNAME [OPTIONS] [NUMBER]...
|
usage: $CMDNAME [OPTIONS] [NUMBER]...
|
||||||
-f, --from=BASE input base. Default is "g"
|
-f, --from=BASE input base, see BASE below. Default is "g"
|
||||||
-t, --to=BASE output base. Default is "a"
|
-t, --to=BASE output base, see BASE below. Default is "a"
|
||||||
-2, -8, -d, -x equivalent to -t2, -t8, -t10, -t16"
|
-b, -o, -d, -x equivalent to -t2, -t8, -t10, -t16"
|
||||||
-g, --group=[SEP] group output (see OUTPUT below)
|
-g, --group=[SEP] group output (see OUTPUT below)
|
||||||
-0, --padding Not implemented. 0-pad output on block boundary (implies -g)
|
-p, --padding 0-pad output on block boundary (implies -g)
|
||||||
-n, --noprefix Remove base prefixes in output
|
-n, --noprefix remove base prefixes in output
|
||||||
-h, --help this help
|
-h, --help this help
|
||||||
|
|
||||||
$CMDNAME output the NUMBERS arguments in different bases. If no NUMBER is
|
$CMDNAME output the NUMBERS arguments in different bases. If no NUMBER is
|
||||||
@@ -40,6 +40,7 @@ BASE
|
|||||||
16, h, H, 0x hexadecimal
|
16, h, H, 0x hexadecimal
|
||||||
a, g all/any: Default, guess format for '-f', output all
|
a, g all/any: Default, guess format for '-f', output all
|
||||||
bases for '-t'
|
bases for '-t'
|
||||||
|
|
||||||
INPUT NUMBER
|
INPUT NUMBER
|
||||||
If input base is not specified, some prefixes are supported.
|
If input base is not specified, some prefixes are supported.
|
||||||
'b' or '2/' for binary, '0', 'o' or '8/' for octal, '0x', 'x' or
|
'b' or '2/' for binary, '0', 'o' or '8/' for octal, '0x', 'x' or
|
||||||
@@ -47,32 +48,52 @@ INPUT NUMBER
|
|||||||
If no prefix, decimal is assumed.
|
If no prefix, decimal is assumed.
|
||||||
|
|
||||||
OUTPUT
|
OUTPUT
|
||||||
By default, output is the input number converted in the 4 supported
|
By default, the input number is shown converted in the 4 supported
|
||||||
bases (16, 10, 8, 2, in this order, separated by one tab character.
|
bases (16, 10, 8, 2, in this order), separated by one tab character.
|
||||||
Without '-n' option, all output numbers but decimal will be prefixed:
|
Without '-n' option, all output numbers but decimal will be prefixed:
|
||||||
'2#' for binary, '0' for octal, '0x' for hexadecimal, making them
|
'2#' for binary, '0' for octal, '0x' for hexadecimal, making them
|
||||||
usable for input in some otilities such as bash(1).]
|
usable for input in some otilities such as bash(1).]
|
||||||
With '-g' option, number digits will be grouped by 3 (octal,
|
With '-g' option, number digits will be grouped by 3 (octal,
|
||||||
decimal), or 4 (binary, hexadecimal)\n. If no SEP character is given,
|
decimal), 4 (hexadecimal), or 8 (binary). If no SEP character is given,
|
||||||
the separator will be ',' (comma) for decimal, space otherwise.
|
the separator will be ',' (comma) for decimal, space otherwise.
|
||||||
This option may be useless if default output, with multiple numbers
|
This option may be useless for default output, with multiple numbers
|
||||||
on one line.
|
on one line.
|
||||||
The '-0' option will left pad with '0' (zeros) to a group boundary.
|
The '-p' option add 0 padding up to the base grouping boundary.
|
||||||
|
|
||||||
EXAMPLES
|
EXAMPLES
|
||||||
|
Converting number in hexadecimal, decimal, octal, and binary, with or without
|
||||||
|
prefixes. Here, '\t' separator is shown as space:
|
||||||
|
$ $CMDNAME 0
|
||||||
|
0x0 0 0 2#0
|
||||||
|
|
||||||
|
$ $CMDNAME -n 2/100
|
||||||
|
4 4 4 100
|
||||||
|
|
||||||
$ $CMDNAME 123456
|
$ $CMDNAME 123456
|
||||||
2#11110001001000000 0361100 123456 0x1e240
|
0x1e240 123456 0361100 2#11110001001000000
|
||||||
$ $CMDNAME -n 123456
|
|
||||||
11110001001000000 361100 123456 1e240
|
$ $CMDNAME -n 0x1e240
|
||||||
$ $CMDNAME -ng2 012345
|
1e240 123456 361100 11110001001000000
|
||||||
1 0100 1110 0101
|
|
||||||
$ $CMDNAME -n2 012345
|
Binary output, no prefix, grouped output:
|
||||||
1 0100 1110 0101
|
$ $CMDNAME -bng 0x1e240
|
||||||
|
1 11100010 01000000
|
||||||
|
|
||||||
|
Input base indication, left padding binary output, no prefix:
|
||||||
|
$ $CMDNAME -nbp -f8 361100
|
||||||
|
00000001 11100010 01000000
|
||||||
|
|
||||||
|
Set group separator. Note that the separator *must* immediately follow the '-g'
|
||||||
|
option, without spaces:
|
||||||
|
$ $CMDNAME -nxg: 123456
|
||||||
|
1:e240
|
||||||
|
|
||||||
_EOF
|
_EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
# some default values (blocks separator padchar)
|
# some default values (blocks separator padchar)
|
||||||
declare -i ibase=0 obase=0 padding=0 noprefix=0 ogroup=0
|
# Attention: For output base 10, obase is 1
|
||||||
|
declare -i ibase=0 obase=0 padding=0 prefix=1 ogroup=0
|
||||||
|
|
||||||
declare -rA _bases=(
|
declare -rA _bases=(
|
||||||
[2]=2 [b]=2 [B]=2
|
[2]=2 [b]=2 [B]=2
|
||||||
@@ -85,22 +106,16 @@ declare -A _pad=(
|
|||||||
[2]=" " [8]=" " [10]="," [16]=" "
|
[2]=" " [8]=" " [10]="," [16]=" "
|
||||||
)
|
)
|
||||||
declare -rA _ogroup=(
|
declare -rA _ogroup=(
|
||||||
[2]=4 [8]=3 [10]=3 [16]=4
|
[2]=8 [8]=3 [10]=3 [16]=4
|
||||||
)
|
)
|
||||||
declare -rA _oprefix=(
|
declare -rA _oprefix=(
|
||||||
[2]="2#" [8]="0" [10]="" [16]="0x"
|
[2]="2#" [8]="0" [10]="" [16]="0x"
|
||||||
)
|
)
|
||||||
|
|
||||||
zero_pad() {
|
zero_pad() {
|
||||||
local base="$1" str="$2"
|
local n="$1" str="$2"
|
||||||
local str="$1"
|
|
||||||
local -i n=${_ogroup[$base]}
|
|
||||||
|
|
||||||
#printf "str=$str #=${#str}" >&2
|
printf "%0.*d%s" $(( n - ${#str} % n)) 0 "$str"
|
||||||
while (( ${#str} < $2 )); do
|
|
||||||
str="0$str"
|
|
||||||
done
|
|
||||||
printf "%s" "$str"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
split() {
|
split() {
|
||||||
@@ -108,14 +123,16 @@ split() {
|
|||||||
local res="$str" sep=${_pad[$base]}
|
local res="$str" sep=${_pad[$base]}
|
||||||
local -i n=${_ogroup[$base]}
|
local -i n=${_ogroup[$base]}
|
||||||
|
|
||||||
|
(( padding )) && str=$(zero_pad "${_ogroup[$base]}" "$str")
|
||||||
if (( ogroup )); then
|
if (( ogroup )); then
|
||||||
res=""
|
res=""
|
||||||
while (( ${#str} )); do
|
while (( ${#str} )); do
|
||||||
if (( ${#str} < n )); then
|
if (( ${#str} <= n )); then # finished
|
||||||
str=$(zero_pad "$str" $n)
|
res="${str}${res:+$sep$res}"
|
||||||
|
break
|
||||||
fi
|
fi
|
||||||
res="${str: -$n}${res:+$sep$res}"
|
res="${str: -n}${res:+$sep$res}"
|
||||||
str="${str:0:-$n}"
|
str="${str:0:-n}"
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
printf "%s" "$res"
|
printf "%s" "$res"
|
||||||
@@ -126,7 +143,7 @@ bin() {
|
|||||||
for (( n = $1 ; n > 0 ; n >>= 1 )); do
|
for (( n = $1 ; n > 0 ; n >>= 1 )); do
|
||||||
bits=$((n&1))$bits
|
bits=$((n&1))$bits
|
||||||
done
|
done
|
||||||
printf "%s\n" "${bits-0}"
|
printf "%s\n" "${bits:-0}"
|
||||||
}
|
}
|
||||||
|
|
||||||
hex() {
|
hex() {
|
||||||
@@ -145,7 +162,7 @@ declare -a args=()
|
|||||||
|
|
||||||
parse_opts() {
|
parse_opts() {
|
||||||
# short and long options
|
# short and long options
|
||||||
local sopts="f:t:28dxg::pnh"
|
local sopts="f:t:bodxg::pnh"
|
||||||
local lopts="from:,to:,group::,padding,noprefix,help"
|
local lopts="from:,to:,group::,padding,noprefix,help"
|
||||||
# set by options
|
# set by options
|
||||||
local tmp=""
|
local tmp=""
|
||||||
@@ -174,9 +191,9 @@ parse_opts() {
|
|||||||
fi
|
fi
|
||||||
shift
|
shift
|
||||||
;;
|
;;
|
||||||
"-2") obase=2 ;;
|
"-b") obase=2 ;;
|
||||||
"-8") obase=8 ;;
|
"-o") obase=8 ;;
|
||||||
"-d") obase=10 ;;
|
"-d") obase=1 ;;
|
||||||
"-x") obase=16 ;;
|
"-x") obase=16 ;;
|
||||||
"-g"|"--group")
|
"-g"|"--group")
|
||||||
ogroup=1
|
ogroup=1
|
||||||
@@ -185,8 +202,8 @@ parse_opts() {
|
|||||||
fi
|
fi
|
||||||
shift
|
shift
|
||||||
;;
|
;;
|
||||||
"-p"|"--padding") padding=1 ;;
|
"-p"|"--padding") ogroup=1; padding=1 ;;
|
||||||
"-n"|"--noprefix") noprefix=1 ;;
|
"-n"|"--noprefix") prefix=0 ;;
|
||||||
"-h"|"--help") help ; exit 0 ;;
|
"-h"|"--help") help ; exit 0 ;;
|
||||||
"--") shift; break ;;
|
"--") shift; break ;;
|
||||||
*) usage; echo "Internal error [$1]!" >&2; exit 1 ;;
|
*) usage; echo "Internal error [$1]!" >&2; exit 1 ;;
|
||||||
@@ -199,19 +216,20 @@ parse_opts() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# shellcheck disable=SC2317
|
|
||||||
addprefix() {
|
addprefix() {
|
||||||
local base="$1" number="$2"
|
local base="$1" number="$2" _prefix=""
|
||||||
local prefix=""
|
if (( prefix )); then
|
||||||
(( noprefix )) || prefix="${_oprefix[$base]}"
|
if [[ $base != 8 || $number != "0" ]]; then
|
||||||
printf "%s%s" "$prefix" "$number"
|
_prefix="${_oprefix[$base]}"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
printf "%s%s" "$_prefix" "$number"
|
||||||
}
|
}
|
||||||
|
|
||||||
stripprefix() {
|
stripprefix() {
|
||||||
local number="$1"
|
local number="$1"
|
||||||
number=${number#0x}
|
number=${number#0x}
|
||||||
number=${number#[bodx0]}
|
number=${number#[bodx]}
|
||||||
number=${number#0}
|
|
||||||
number=${number#*/}
|
number=${number#*/}
|
||||||
printf "%s" "$number"
|
printf "%s" "$number"
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user