テキストファイルの行と列が交差する頻度を印刷します。

テキストファイルの行と列が交差する頻度を印刷します。

次のファイルがあります。

1
2 4 5 6 
20
22
24 26 27 
29 30 31 32 34 40 50 56 58
234 235 270 500
1234 1235 1236 1237
2300

4行と1列、3行と4列、1行と3列、1行と9列を表示する出力が必要です。したがって、出力は次のようになります。 row(column)

4 (1)
1 (3)
3 (4)
1 (9)

私の実際のデータがかなり大きいことを考えると、どのような提案がありますか?同時に、最後の行(ここでは9つ)に最大列数を表示し、出力の最初の行に最小列数を表示しようとしています。

答え1

最新(> 4.0)バージョンのGNU awkを使用している場合:

gawk '
  {a[NF]++} 
  END {
    PROCINFO["sorted_in"]="@ind_num_asc"; 
    for (i in a) printf "%d (%d)\n", a[i], i;
  }' file
4 (1)
1 (3)
3 (4)
1 (9)

答え2

愚かな方法(asorti機能を使用):

awk '{a[NF]++}END{ asorti(a,b); for(i in b) printf("%d (%d)\n",a[b[i]],b[i]) }' file

出力:

4 (1)
1 (3)
3 (4)
1 (9)

  • asorti(a,b)- インデックスによる配列の並べ替え

答え3

目的の結果を生成するためにテーブル内の各セルをプレースホルダとして処理する場合は、重複行を並べ替えて計算して、同じ数の列を持つ行数を確認できます。

a=$(sed 's/\([0-9]\+\)/1/g' file | sort | uniq -c)
dups=$( echo "$a" | cut -d' ' -f7 )

その後、各行の単語数を計算して、その行にいくつの列があるかを確認できます。

words=$(echo "$a" | cut -d' ' -f8- | awk '{print NF}')
paste <(echo "$dups") <(echo "$words")
4       1
1       3
3       4
1       9

答え4

最も簡単なバージョンは

cat data.txt | awk '{counts[NF] += 1} END { for (row_count in counts) { printf "%d (%d)\n", counts[row_count], row_count; }'

単にNF変数を使用して行のフィールド数を提供し、辞書でそれに関連する関連値を更新します。次に、ストリームの終わりに辞書のすべてのキーを繰り返し、要求された形式で印刷します。

関連情報