21

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

所以转换这个:

937
1.43K
120.3M

到:

937
1464
126143693

我负担得起,我预计会出现一些舍入错误。

提前致谢。

PS 不必是 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

4

5 回答 5

35

numfmt --from=iec从 GNU coreutils使用。

于 2019-01-28T15:14:26.030 回答
20

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

dehumanise() {
  for v in "${@:-$(</dev/stdin)}"
  do  
    echo $v | awk \
      'BEGIN{IGNORECASE = 1}
       function printpower(n,b,p) {printf "%u\n", 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
} 

例子:

$ dehumanise 2K 2k 2KiB 2KB 
2048
2048
2048
2000

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

后缀不区分大小写。

于 2015-07-25T09:55:34.243 回答
7
$ cat dehumanise 
937
1.43K
120.3M

$ awk '/[0-9]$/{print $1;next};/[mM]$/{printf "%u\n", $1*(1024*1024);next};/[kK]$/{printf "%u\n", $1*1024;next}' dehumanise
937
1464
126143692
于 2014-10-29T02:25:44.447 回答
5

存在 Python 工具

$pip install humanfriendly  # Also available as a --user install in ~/.local/bin

$humanfriendly --parse-size="2 KB"
2000
$humanfriendly --parse-size="2 KiB"
2048
于 2017-09-22T21:30:10.510 回答
1

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

这是对@starfry 答案的修改。


让我们分解一下:

函数 pp(p) { printf "%u\n", $0 * 1024^p }

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

/[0-9]$/ { 打印 $0 }

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

/K$/ { pp(1) }

匹配以大写字母结尾的行K,调用函数 pp() 并将 1 传递给它(p == 1)。 注意:当在数学方程式中使用 $0(例如“1.43K”)时,下面将只使用开头的数字(即“1.43”)。$0 = "1.43K" 的示例

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

/M$/ { pp(2) }

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

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

等等...对于GT

/[^0-9KMGT]$/ { 打印 0 }

不以数字或大写字母 K、M、G 或 T 结尾的行打印“0”。


例子:

$ cat dehumanise
937
1.43K
120.3M
5G
933G
12.2T
bad
<>

结果:

$ awk 'function pp(p){printf "%u\n",$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
于 2018-10-14T04:34:17.807 回答