关于linux:在bash中将人类可读转换为字节

Convert human readable to bytes in bash

因此,我试图在Linux中分析非常大的日志文件,我已经看到了很多与此相反的解决方案,但是记录数据的程序不允许输出格式,因此它只能以人类可读的格式输出(我知道,这是多么痛苦)。因此,问题是:如何使用awk之类的东西将人类可读性转换为字节:

所以转换这个:

1
2
3
937
1.43K
120.3M

到:

1
2
3
937
1464
126143693

我负担得起,而且我预计会有一些舍入误差。

事先谢谢。

P.S.不必是awk,只要它可以提供在线转换。

我发现了这个,但是给出的awk命令似乎不能正常工作。它输出大约534K"0"。

我还发现了一个使用SED和BC的解决方案,但是因为它使用BC,所以它的有效性有限,这意味着它一次只能使用一个列,并且所有数据都必须适合BC,否则它会失败。

sed -e 's/K/\*1024/g' -e 's/M/\*1048576/g' -e 's/G/\*1073741824/g' | bc


下面是一个函数,它可以理解二进制和十进制前缀,如果需要的话,可以很容易地扩展到大型单元:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
dehumanise() {
  for v in"${@:-$(</dev/stdin)}"
  do  
    echo $v | awk \
      'BEGIN{IGNORECASE = 1}
       function printpower(n,b,p) {printf"%u
", n*b^p; next}
       /[0-9]$/{print $1;next};
       /K(iB)?$/{printpower($1,  2, 10)};
       /M(iB)?$/{printpower($1,  2, 20)};
       /G(iB)?$/{printpower($1,  2, 30)};
       /T(iB)?$/{printpower($1,  2, 40)};
       /KB$/{    printpower($1, 10,  3)};
       /MB$/{    printpower($1, 10,  6)};
       /GB$/{    printpower($1, 10,  9)};
       /TB$/{    printpower($1, 10, 12)}'

  done
}

例子:

1
2
3
4
5
6
7
8
9
10
11
$ dehumanise 2K 2k 2KiB 2KB
2048
2048
2048
2000

$ dehumanise 2G 2g 2GiB 2GB
2147483648
2147483648
2147483648
2000000000

后缀不区分大小写。


1
2
3
4
5
6
7
8
9
10
cat dehumanise
937
1.43K
120.3M
awk '/[0-9]$/{print $1;next};/[mM]$/{printf"%u
", $1*(1024*1024);next};/[kK]$/{printf"%u
", $1*1024;next}'
dehumanise
937
1464
126143692


使用GNU coreutils的numfmt --from=iec


存在python工具

1
2
3
4
5
6
$pip install humanfriendly  # Also available as a --user install in ~/.local/bin

$humanfriendly --parse-size="2 KB"
2000
$humanfriendly --parse-size="2 KiB"
2048


awk 'function pp(p){printf"%u
",$0*1024^p} /[0-9]$/{print
$0}/K$/{pp(1)}/M$/{pp(2)}/G$/{pp(3)}/T$/{pp(4)}/[^0-9KMGT]$/{print 0}'

这是对@starfray答案的修改。

让我们把它分解一下:

function pp(p) { printf"%u
", $0 * 1024^p }

定义一个名为pp的函数,该函数接受单个参数p并打印$0乘以提升到p-th幂的1024。%u将打印该数字的无符号十进制整数。

/[0-9]$/ { print $0 }

匹配以数字结尾的行($与行尾匹配),然后在{}中运行代码。打印整行($0)

/K$/ { pp(1) }

匹配以大写字母K结尾的行,调用函数p p()并将1传递给它(p==1)。注:当数学公式中使用$0(例如"1.43K")时,以下仅使用起始数字(即"1.43")。例如$0="1.43K"

1
$0 * 1024^p == 1.43K * 1024^1 == 1.43K * 1024 = 1.43 * 1024 = 1464.32

/M$/ { pp(2) }

匹配以大写字母M结尾的行,调用函数p p()并将2传递给它(p==2)。例如,$0="12030万"

1
$0 * 1024^p == 120.3M * 1024^2 == 120.3M * 1024^2 == 120.3M * 1024*1024 = 120.3 * 1048576 = 126143692.8

等。。。对于GT

/[^0-9KMGT]$/ { print 0 }

不以数字或大写字母k、m、g或t结尾的行打印"0"。

例子:

1
2
3
4
5
6
7
8
9
$ cat dehumanise
937
1.43K
120.3M
5G
933G
12.2T
bad
<>

结果:

1
2
3
4
5
6
7
8
9
10
$ awk 'function pp(p){printf"%u
",$0*1024^p} /[0-9]$/{print $0}/K$/{pp(1)}/M$/{pp(2)}/G$/{pp(3)}/T$/{pp(4)}/[^0-9KMGT]$/{print 0}'
dehumanise
937
1464
126143692
5368709120
1001801121792
13414041858867
0
0