多数の数字(数字のみ、各数字が1行にある)を含むファイルがあります。数値が100(または実際には他の値)より大きい行数を探したいと思います。どうすればいいですか?
答え1
このテストファイルを考えてみましょう。
$ cat myfile
98
99
100
101
102
103
104
105
それでは、100より大きい数値を含む行数を計算してみましょう。
$ awk '$1>100{c++} END{print c+0}' myfile
5
どのように動作しますか?
$1>100{c++}
行の数が 100 を超えるたびに、変数は
c
1 ずつ増加します。END{print c+0}
ファイルの読み取りが終了すると、変数が
c
印刷されます。0
に追加すると、awkはそれを数値として扱うように強制c
します。c
数字のある行がある場合は、すでに数字>100
ですc
。それ以外の場合はc
空です(ヒント:イルバル)。ここに0を追加すると、空の文字列をaに変更して0
より正確な出力を提供します。
答え2
同様のソリューションperl
$ seq 98 105 | perl -ne '$c++ if $_ > 100; END{print $c+0 ."\n"}'
5
速度比較:3回連続実行について報告された数
任意の文書:
$ perl -le 'print int(rand(200)) foreach (0..10000000)' > rand_numbers.txt
$ perl -le 'print int(rand(100200)) foreach (0..10000000)' >> rand_numbers.txt
$ shuf rand_numbers.txt -o rand_numbers.txt
$ tail -5 rand_numbers.txt
114
100
66125
84281
144
$ wc rand_numbers.txt
20000002 20000002 93413515 rand_numbers.txt
$ du -h rand_numbers.txt
90M rand_numbers.txt
そしてawk
$ time awk '$1>100{c++} END{print c+0}' rand_numbers.txt
14940305
real 0m7.754s
real 0m8.150s
real 0m7.439s
そしてperl
$ time perl -ne '$c++ if $_ > 100; END{print $c+0 ."\n"}' rand_numbers.txt
14940305
real 0m4.145s
real 0m4.146s
real 0m4.196s
楽しさでgrep
(修正する:LC_ALL = Cの場合、Perlよりはるかに高速です。
$ time grep -xcE '10[1-9]|1[1-9][0-9]|[2-9][0-9]{2,}|1[0-9]{3,}' rand_numbers.txt
14940305
real 0m10.622s
$ time LC_ALL=C grep -xcE '10[1-9]|1[1-9][0-9]|[2-9][0-9]{2,}|1[0-9]{3,}' rand_numbers.txt
14940305
real 0m0.886s
real 0m0.889s
real 0m0.892s
sed
まったく面白くない:
$ time sed -nE '/^10[1-9]|1[1-9][0-9]|[2-9][0-9]{2,}|1[0-9]{3,}$/p' rand_numbers.txt | wc -l
14940305
real 0m11.929s
$ time LC_ALL=C sed -nE '/^10[1-9]|1[1-9][0-9]|[2-9][0-9]{2,}|1[0-9]{3,}$/p' rand_numbers.txt | wc -l
14940305
real 0m6.238s