各列の各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,
答え2
使用幸せ(以前のPerl_6)
~$ raku -e 'my @a = [Z] lines.map: *.split(","); my @b; \
for ^@a -> $row { \
for ^$row.elems -> $col { my %h; \
%h{$_}++ for @a[$row]>>.[$col]; \
@b.push: %h.sort }}; \
for ^@b>>.elems.max -> $j { \
put @b.map({ $_.[$j] // (" " => "0") }).join: "," };' file
または(より簡単に):
~$ raku -e 'my @a = [Z] lines.map: *.split(","); my @b; \
for ^@a -> $row { \
my %h is BagHash = @a[$row]; \
@b.push: %h.sort }; \
for ^@b>>.elems.max -> $j { \
put @b.map({ $_.[$j] // (" " => "0") }).join: "," };' file
以下は、Perlシリーズのプログラミング言語であるRakuで書いた答えです。 RakuにはUnicodeの高度なサポート機能が組み込まれています。上記のコードは、@
署名された配列や署名付き%
ハッシュ(辞書とキーと値のペアなど)などのさまざまなPerl機能を利用します。
まず、データを1行ずつ読み、
lines
各データをsplit
カンマで区切ります。行と列を置き換えるには、[Z]
演算子を使用してデータを@a
配列に保存します。次に、
@a
配列は最初にby、$row
次に繰り返され、$col
各$row
セルに対して「キー」()がハッシュ(最初の答え)またはBagHash(2番目の答え)$_
に格納されます。%h
各行が解析された後、キー/値データが配列@b
に保存されます。最後に、
max
キー/値の数を決定し(通過)データを出力します。特定の列のキーが未定義の場所にゼロを挿入するように注意してください(OPはここで代わりに使用できます)。elems
put
0
"Nil"
" "
入力例(列のキー数が等しくない):
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,X
L,L,L,L
G,G,G,G
出力例(キーと値のペアタブ\t
で区切られています):
A 4,A 1,A 1,A 1
C 1,C 1,C 1,C 1
G 1,G 1,G 4,G 1
L 1,L 1,L 1,L 4
M 1,M 3,M 1,M 1
N 1,N 3,N 1,N 1
P 2,P 1,P 2,P 1
0, 0, 0,X 1
https://docs.raku.org/type/BagHash
https://docs.raku.org
https://raku.org