21

だから私はLinuxで非常に大きなログファイルを分析しようとしており、これの逆の解決策をたくさん見てきましたが、データを記録するプログラムは出力フォーマットを許可していないため、人間が読める形式でのみ出力します(私は知っています、なんて痛い)。質問は次のとおりです。awkのようなものを使用して、人間が読める形式をバイトに変換するにはどうすればよいですか:

したがって、これを変換します:

937
1.43K
120.3M

に:

937
1464
126143693

私は余裕があり、いくつかの丸め誤差が予想されます。

前もって感謝します。

PSインライン変換を提供できる限り、面倒である必要はありません。

これを見つけましが、指定された awk コマンドが正しく機能していないようです。534K"0" のようなものを出力します。

sed と bc を使用した解決策も見つけましたが、bc を使用しているため効果が制限されており、一度に 1 つの列しか使用できず、すべてのデータが bc に適切である必要があり、そうでない場合は失敗します。

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

4

5 に答える 5

20

これは、2 進数と 10 進数のプレフィックスを理解し、必要に応じて大きな単位に簡単に拡張できる関数です。

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 '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}'

This is a modification on @starfry's answer.


Let's break it down:

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

Define a function named pp that takes a single parameter p and prints the $0 multiplied by 1024 raised to the p-th power. The %u will print the unsigned decimal integer of that number.

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

Match lines that end with a digit (the $ matches the end of the line), then run the code inside the { and }. Print the entire line ($0)

/K$/ { pp(1) }

Match lines that end with the capital letter K, call the function pp() and pass 1 to it (p == 1). NOTE: When $0 (e.g. "1.43K") is used in a math equation only the beginning numbers (i.e. "1.43") will be used below. Example with $0 = "1.43K"

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

/M$/ { pp(2) }

Match lines that end with the capital letter M, call the function pp() and pass 2 to it (p == 2). Example with $0 == "120.3M"

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

etc... for G and T

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

Lines that do not end with a digit or the capital letters K, M, G, or T print "0".


Example:

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

Results:

$ 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 に答える