ファイル内の科学的な数値の数を数えるにはどうすればよいでしょうか? ファイルにはスキップする必要があるヘッダー行もいくつかあります。
ファイルの内容の一部を以下に示します。
FileHeaderLine1
FileHeaderLine2
FileHeaderLine3
FileHeaderLine4
2.91999996E-001 2.97030300E-001 3.02060604E-001 3.07090908E-001 3.12121212E-001 3.17151517E-001
3.22181821E-001 3.27212125E-001 3.32242429E-001 3.37272733E-001 3.42303038E-001 3.47333342E-001
3.52363646E-001 3.57393950E-001 3.62424254E-001 3.67454559E-001 3.72484863E-001 3.77515137E-001
3.82545441E-001 3.87575746E-001 3.92606050E-001 3.97636354E-001 4.02666658E-001 4.07696962E-001
4.12727267E-001 4.17757571E-001 4.22787875E-001 4.27818179E-001 4.32848483E-001 4.37878788E-001
4.42909092E-001 4.47939396E-001 4.52969700E-001
では、上記の例の最初の 4 行をスキップして、ファイル内の科学的数値の数を数えるにはどうすればよいでしょうか?
答え1
コアモジュールを使用するとScalar::Util
、次のことが可能になります。
$ perl -MScalar::Util=looks_like_number -anle '
$count += grep { looks_like_number($_) } @F;
END { print $count }
' file
33
詳細についてはlooks_like_number
をご覧くださいperldoc perlapi
。
答え2
GNU grepの使用
PCRE 機能を使用してこれを行うことができますgrep
。ちなみに、同じパターンは Perl でも使用できます。
$ grep -oP '\d+E[-+]?\d+' file.txt | wc -l
33
単語を数えるためにも を使用できますwc -w
。上記では行を数えていますが、grep
は行に 1 つの一致を返すため、このシナリオではそれほど重要ではありません。
Perlの使用
Perl の場合は、次のワンライナーを使用できます。
$ perl -lane '$c += grep /\d+E[-+]?\d+/, @F; END { print $c; }' file.txt
33
参考文献
答え3
egrep
働くでしょう:
egrep "[0-9].[0-9]E-[0-9]" YourFile | wc -w
アップデート:
行に数字と他の文字列の両方が含まれている場合は、次のようにしてawk
問題を解決できます。
awk -F' ' '{for(i=1;i<=NF;i++)if(!(i%1))$i=$i "\n"}1' YourFile | egrep "[0-9].[0-9]E-[0-9]" | wc -w ( or wc -l )
答え4
単に数を数える必要がある場合は、空白で区切られたフィールドPerlのヘッダー行に続いて、次のようにすればよいと思います。
perl -lane '$sum += $#F+1 if $. > 4; END{print $sum}' file
本当に科学的にフォーマットされた数字だけを数える必要がある場合は、次のように数字を検索して置換するという方法があります。適切な正規表現そして、置換の数を数えます(Perlの置換式は、変数にバインドすると置換の数を返します)。
perl -lane '$sum += s/[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?//g if $. > 4; END{print $sum}' file