awk:各列の各固有文字列の総数とその列の順序で出力

awk:各列の各固有文字列の総数とその列の順序で出力

各列の各uniq文字列の総数(合計)を取得し、その列の順序で出力しようとしています。

さまざまな入力全体が何千もの行と列であることが多いため、強力なawkコマンドでこれを使用する必要があります。

私はこれを自分で試しましたが、運がありませんでした。かなり近いと思います。明らかに動作しませんが、コードを使用する場所は次のとおりです。

awk -F ',' '{ for(N=1; N<=NF; N++) {{count[$N]++} END {for (word in count) print word, count[word]}}}'

上記のコードについての私の考えは、実行すると、指定された単一の列に対して目的の出力を取得できることです。それでは、列2を仮定しましょう。

awk '{count[$2]++} END {for (word in count) print word, count[word]}'

ただし、各列にはこのタイプの出力が必要です。だからこれを達成するために列を繰り返そうとしましたが、失敗しました。

以下は、いくつかのサンプルデータです。

入力例:

M,M,M,M
N,N,N,N    
A,M,G,L
P,P,P,P
A,N,G,L    
P,N,P,L
A,A,A,A
C,C,C,C
A,M,G,C
L,L,L,L
G,G,G,G

対応する予想出力:

M 1,M 2,M 1,M 1
N 1,N 2,N 1,N 1
A 3,A 1,A 1,A 1
P 1,P 1,P 1,P 1
L 1,L 1,L 1,L 3
G 1,G 1,G 3,G 1
C 1,C 1,C 1,C 1

出力を説明するために、入力例の最初の列には3つのAsがあり、他のすべての文字はそれぞれ1つしかないため、その列の出力は次のようになります。
M 1
N 1
A 3
P 1
L 1
G 1
C 1

私はこのコードを書いたがうまくいきますが、理想的にはawkコマンドで実装したいと思います。

for i in $(seq $NumberOfColumns);do
ColumnOutput=$(awk -F ',' -v x=$i '{count[$x]++} END {for (word in count) print word, count[word]}' file)
TotalOutput=$(paste <(echo "$TotalOutput") <(echo "$ColumnOutput") -d ,)
done    
echo "$TotalOutput" | sed 's/^,//g'    

ベストアンサー1

私はこれが役に立つと思います:

$ awk -F"," '              
    NR==FNR { for (i=1;i<=NF;i++) {a[i,$i]+=1;b[$i]=$i} next }
    { for (i=1;i<=NF;i++)if(b[$1]) printf "%s %s,",$1,a[i,$1];else next; print ""; delete b[$1] }
' file file
M 1,M 3,M 1,M 1,
N 1,N 3,N 1,N 1,
A 4,A 1,A 1,A 1,
P 2,P 1,P 2,P 1,
C 1,C 1,C 1,C 2,
L 1,L 1,L 1,L 3,
G 1,G 1,G 4,G 1,

おすすめ記事