jak*_*sky 3 shell bash arithmetic
我需要将人类可读的大小转换为字节。不幸的是,我无法访问 numfmt 函数。还有其他选择吗?我需要一个 shell/bash 函数来从 sh 脚本内部调用。
1K 应转换为 1000,1M 应转换为 1000 000 等。
如果 Perl 可用:
echo your_string | perl -ne '
BEGIN{ %suffixes=( K => 3, M => 6, G => 9, T => 12, P => 15, E => 18 );
$suffix_regex = join "|", keys %suffixes;
}
s/([0-9][0-9]*(?:\.[0-9]+)?)($suffix_regex)/$1e$suffixes{$2}/g;
printf "%d\n", $_;
'
Run Code Online (Sandbox Code Playgroud)
由于这将用作文本过滤器,因此将其定义为perl脚本并将输入管道输入其中更为合适。您可以通过将以下内容添加到您的.bashrc(假设您使用 Bash)将其嵌入到 shell 函数中:
myconvert() {
cat <<'EOF' >/dev/null
#!--perl-- -n
BEGIN{ %suffixes=( K => 3, M => 6, G => 9, T => 12, P => 15, E => 18 );
$suffix_regex = join "|", keys %suffixes;
}
s/([0-9][0-9]*(?:\.[0-9]+)?)($suffix_regex)/$1e$suffixes{$2}/g;
printf "%d\n", $_;
__END__
EOF
exec perl -x "/path/to/your/.bashrc"
}
Run Code Online (Sandbox Code Playgroud)
使用sed和的解决方案bc:
myconvert(){
sed '
s/\([0-9][0-9]*\(\.[0-9]\+\)\?\)K/\1*1000/g;
s/\([0-9][0-9]*\(\.[0-9]\+\)\?\)M/\1*1000000/g;
s/\([0-9][0-9]*\(\.[0-9]\+\)\?\)G/\1*1000000000/g;
s/\([0-9][0-9]*\(\.[0-9]\+\)\?\)T/\1*1000000000000/g;
s/\([0-9][0-9]*\(\.[0-9]\+\)\?\)P/\1*1000000000000000/g;
s/\([0-9][0-9]*\(\.[0-9]\+\)\?\)E/\1*1000000000000000000/g
' </dev/stdin | bc | sed 's/\..*$//' # Final sed to remove decimal point
}
Run Code Online (Sandbox Code Playgroud)
用法(两种解决方案相同):
$ echo '5.23K' | myconvert
5230
$ echo '6.27G' | myconvert
6270000000
Run Code Online (Sandbox Code Playgroud)
此解决方案假定您的输入仅包含形式的字符串5.23K(小数部分可选),否则bc将不知道如何处理它们。
笔记
Perl one-liner 可以按原样插入到 shell 函数中,< /dev/stdin就像sed解决方案一样。在编写答案的第一个版本时,我并没有想到这一点。不过,我将把perl -x诀窍留在那里,以防它可以使其他人受益。