I want to convert all values with kb,mb,gb,b to the real bytes, for example, "10kb" should be convert to "10240" bytes.
Here is the test function:
#! /bin/bash
get_value_in_bytes()
{
local value="$1"
local unit_length=0
local number_length=0
local number=0
if [[ "$value" == *"gb" ]]
then
unit_length=2
number_length=$((${#value} - $unit_length))
number=$((${value:0:$number_length})) * 1024 * 1024 * 1024 || -1
elif [[ "$value" == *"mb" ]]
then
unit_length=2
number_length=$((${#value} - $unit_length))
number=$((${value:0:$number_length}))*1024*1024 || -1
elif [[ "$value" == *"kb" ]]
then
unit_length=2
number_length=$((${#value} - $unit_length))
number=$((${value:0:$number_length}))*1024 || -1
elif [[ "$value" == *"b" ]]
then
unit_length=1
number_length=$((${#value} - $unit_length))
number=$((${value:0:$number_length})) || -1
else
number=$((${value:0:$number_length})) || -1
fi
if (( $number < 0 ))
then
echo "error : $value"
else
echo "$number : $value"
fi
}
Here is the test:
get_value_in_bytes 10kb
get_value_in_bytes 10mb
get_value_in_bytes 10gb
get_value_in_bytes 10b
get_value_in_bytes 10
get_value_in_bytes not_number_mb
get_value_in_bytes not_number_gb
Here is the output:
10*1024 : 10kb
10*1024*1024 : 10mb
./test.sh: line 15: test.sh: command not found
./test.sh: line 15: -1: command not found
0 : 10gb
10 : 10b
0 : 10
0*1024*1024 : not_number_mb
./test.sh: line 15: test.sh: command not found
./test.sh: line 15: -1: command not found
0 : not_number_gb
I want this function can accept any values as input, and if the value is not number string, then convert it to -1. But the above function doesn't work as expected.
CodePudding user response:
Here's a solution based on a bash ERE and a case
statement:
get_value_in_bytes() {
local bytes=-1
if [[ $1 =~ ^([[:digit:]] )(b|kb|mb|gb)?$ ]]
then
bytes=${BASH_REMATCH[1]}
case ${BASH_REMATCH[2]} in
kb) bytes=$((bytes * 1024)) ;;
mb) bytes=$((bytes * 1048576)) ;;
gb) bytes=$((bytes * 1073741824)) ;;
esac
fi
printf '%s\n' "$bytes"
}
remarks:
With shell arithmetic you can only process integers, so for floating point numbers you'll have to use
bc
.b
meansbit
, you should useB
when you meanbyte
.To be correct, the units based on
2^10
areKiB
MiB
GiB
, etc...