ファイル内のすべての文字列の発生回数を計算し、各文字列の平均値を取得する方法

ファイル内のすべての文字列の発生回数を計算し、各文字列の平均値を取得する方法

特定の文字列を指定せずにgrepを使用して繰り返される各文字列の数を印刷するには、cutコマンドの出力を使用して発生回数を計算しようとしています。その後、numaverageを使用して平均を取得したいのですが、最初に数字を削除せずにこれを行う方法がわかりません。
まず、 cut -d " " -f 1 $file 次のコマンドを使用してファイルの左側の部分のみを表示できるように半分に減らしました。

NEUTRON   20.900103
PION-      0.215176
PION-     22.716532
NEUTRON    8.043279
PION+      1.374297
PION-      0.313350
PION+      0.167848

それまではただ

NEUTRON  
PION-     
PION-     
NEUTRON    
PION+      
PION-      
PION+      

このようにcut、grep、numaverageを一緒に実行するにはどうすればよいですか(例えば、cat、uniq、wcなどの他のコマンドが役に立ちます)。前の出力:

Name          count     Average
KAON-            1      5.489958
NEUTRON          2      14.471691
PHOTON          10      0.652727
PION-            5      5.145192
PION+            7      2.691639
PROTON           1      1.160216

答え1

使用先csvsqlcsvkit

ファイルがスペースで区切られた場合:

csvsql -d' ' -S -H --query 'select a as Name, count(*) as count, avg(b) as Average from file group by a' file \
    | csvformat -D' '

または、ファイルがタブ区切りの場合:

csvsql -t -S -H --query 'select a as Name, count(*) as count, avg(b) as Average from file group by a' file \
    | csvformat -T

出力:

Name    count   Average
NEUTRON 2   14.471691
PION+   2   0.7710725
PION-   3   7.74835266667

次のコマンドを使用してインストールする必要がありますpip

pip install csvkit

答え2

努力するawk

awk '
    BEGIN{FS=OFS="\t"} # if your file is space-delimited, leave this out
    {c[$1]++;v[$1]+=$2}
    END{
        print "Name","count","Average"
        for(f in c){print f,c[f],v[f]/c[f]}
    }
' file

答え3

どちらの回答(SQL、AWK)も標準言語であり、慣用的な方法でアルゴリズムを実装しているので気に入っています。しかし、Qが特定の解決策に固執するようだったので、Qにさらに反対する予定でした。

しかし、これはfgdarkの問題です。ユーティリティに依存しすぎて、関連するアルゴリズムを理解していません。

このマナーでは、cut、grep、numaverageをどのように一緒に結合します(cat、uniq、wcなどの他のコマンドが役に立つかもしれません)?

一時ファイルから始めて、配管ソリューションを「簡単に」見つけることができ、チェーンが機能するときに一緒に配管することができます。結果は満足できないでしょう。まず、平均はありません。パフォーマンスも。

これには、SQLやAWKなどの「実際の」プログラミング言語が必要です。またはperlやPython、C.またはbash - しかし、bashはスクリプト言語として使用されます連想配列そして算術演算子、"ちょうど" bashをシェルとして使用する代わりに。

平均は必要ありません()機能SQLソリューションと同様に、読み取ったデータを配列として計算、追加、分割するだけです。

したがって、より多くのデータ報告を実行するには、以下を選択する必要があります。言語。 SQLは少し特別です。データに強みがあります。採鉱。言及されている他のもの(awk、perl、python、C、さらにはbash)はすべてデータに関して強力です。処理(変数/配列/構造操作)。しかし、かなりの重複があります。


私は数年間SQLを使用してきました。クエリと呼び出しを保存する方法は次のとおりです。

SQL='select a as Name, count(*) as Count, avg(b) as Average' 
SQL+=' from file'
SQL+=' group by a'

csvsql -tSH --query $SQL file | csvformat -T

これは批判ではなく、構造的なクエリ言語がどのように -構造化。これはgroup by、集計関数sumがあるcount句の教科書のデモですavg

+=Bashはこれを簡単に実行できる構文を提供します。

関連情報