複数のファイルの特定の文字列の後に数値をgrepして平均を返す正規表現

複数のファイルの特定の文字列の後に数値をgrepして平均を返す正規表現

複数のファイルから特定の文字列に続くすべての数値の平均を返したいと思います。

10個のファイル(file1.txt、...、file10.txt)があります。各ファイルには異なるコンテンツが含まれています。

Test1: Avg. length 24.01000, time: 0.579
Test2: Avg. length 22.02000, time: 0.879

別の数字で。

10個のファイルがある場合は、次のようになります。

ファイル1.txt

Test1: Avg. length 24.01000, time: 0.679
Test2: Avg. length 22.01000, time: 0.479

ファイル2.txt

Test1: Avg. length 27.01000, time: 0.279
Test2: Avg. length 24.01000, time: 0.779

ファイル10.txt

私が望む出力は、すべてのファイルでTest1とTest2の長さと時間の平均です。

Mean Test1: Avg. length (file1_Test1_length+...+file10_Test1_lenght)/10, time (file1_Test1_time+...+file_10_Test1_time)/10
Mean Test2: Avg. length (file1_Test2_length+...+file10_Test2_lenght)/10, time (file1_Test2_time+...+file_10_Test2_time)/10

Test1の出力全体をgrepするには、次のようにします。

egrep -rh 'Test1: Avg. length.*' /home/timo/Documents

数字だけをgrepする方法がわかりません。頑張った

egrep -rhP '(?<=length )\d+' /home/timo/Documents

しかし、エラーが発生しました。

grep: conflicting matchers specified

誰でも私を助けることができればとても感謝します!

ベストアンサー1

次のawk解決策が機能します。

awk -F'[ ,:]+' '$1~/^Test[12]/{l[$1]+=$4; t[$1]+=$6; n[$1]++;}
                END{if (n["Test1"]) {for (tst in l) printf("Mean %s: Avg. length %f, time: %f\n",tst,l[tst]/n[tst], t[tst]/n[tst]);} else {print "No input found"}}' file*.txt

Test1これにより、入力ファイル内のorで始まる行とTest2合計フィールド4と6(それぞれ「長さ」と「時間」)が解析されます。また、データカウンタも増加しますn。最後に、平均値(データが見つかった場合)またはエラーメッセージを印刷します。

少なくとも1つのファイルが存在すると確信している場合は、次のように単純化できます。

awk -F'[ ,:]+' '$1~/^Test[12]/{l[$1]+=$4; t[$1]+=$6; n[$1]++;}
                END{for (tst in l) printf("Mean %s: Avg. length %f, time: %f\n",tst,l[tst]/n[tst], t[tst]/n[tst]);}' file*.txt

すべてのファイルが別々のサブフォルダーにあるように見えるため、方法はシェルによって異なります。最も簡単な場合は試してみてください。

awk -F'[ ,:]+' ' ... ' subdir*/file*.txt

おすすめ記事