如何在 Bash 脚本中计算 kb,mb,gb,b 的真实值
How to calculate the real value in kb,mb,gb,b in Bash script
我想将所有带有 kb,mb,gb,b 的值转换为实际字节,例如,“10kb”应转换为“10240”字节。
这里是测试函数:
#! /bin/bash
get_value_in_bytes()
{
local value=""
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
}
这是测试:
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
这是输出:
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
我希望这个函数可以接受任何值作为输入,如果该值不是数字字符串,则将其转换为-1。但是上面的功能并没有达到预期的效果。
这是一个基于 bash ERE 和 case
语句的解决方案:
get_value_in_bytes() {
local bytes=-1
if [[ =~ ^([[: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"
}
备注:
Shell算术只能处理整数。对于浮点计算,您必须使用外部工具,例如 bc
.
b
单位适用于 bit
。当你的意思是 byte
时,你应该使用 B
。
旁白:基于2^10
的单位是KiB
MiB
GiB
等...
作为说明,并不总是需要使用 Bash 的正则表达式;这里 仅使用 POSIX-shell 语法重写:
#!/usr/bin/env sh
toBytes() {
digits=${1%%[^[:digit:]]*}
unit=${1##*[[:digit:] ]}
case $unit in
kb) bytes=$((digits * 1024)) ;;
mb) bytes=$((digits * 1048576)) ;;
gb) bytes=$((digits * 1073741824)) ;;
b | '') bytes=$((digits)) ;;
*) bytes=-1 ;;
esac
printf '%s\n' "$bytes"
}
for s in 10kb 10mb 10gb 10b 10 not_number_mb not_number_gb; do
toBytes "$s"
done
我想将所有带有 kb,mb,gb,b 的值转换为实际字节,例如,“10kb”应转换为“10240”字节。
这里是测试函数:
#! /bin/bash
get_value_in_bytes()
{
local value=""
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
}
这是测试:
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
这是输出:
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
我希望这个函数可以接受任何值作为输入,如果该值不是数字字符串,则将其转换为-1。但是上面的功能并没有达到预期的效果。
这是一个基于 bash ERE 和 case
语句的解决方案:
get_value_in_bytes() {
local bytes=-1
if [[ =~ ^([[: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"
}
备注:
Shell算术只能处理整数。对于浮点计算,您必须使用外部工具,例如
bc
.b
单位适用于bit
。当你的意思是byte
时,你应该使用B
。旁白:基于
2^10
的单位是KiB
MiB
GiB
等...
作为说明,并不总是需要使用 Bash 的正则表达式;这里
#!/usr/bin/env sh
toBytes() {
digits=${1%%[^[:digit:]]*}
unit=${1##*[[:digit:] ]}
case $unit in
kb) bytes=$((digits * 1024)) ;;
mb) bytes=$((digits * 1048576)) ;;
gb) bytes=$((digits * 1073741824)) ;;
b | '') bytes=$((digits)) ;;
*) bytes=-1 ;;
esac
printf '%s\n' "$bytes"
}
for s in 10kb 10mb 10gb 10b 10 not_number_mb not_number_gb; do
toBytes "$s"
done