特定数の列を持つ行数の計算

特定数の列を持つ行数の計算

次の内容を含む複数のファイルがあります。

GGHTERR_01218   GGHTERR_02418   GGHTERR_01991
GGHTERR_02211   GGHTERR_02297   GGHTERR_02379
GGHTERR_02294   GGHTERR_02455   GGHTERR_02374
GGHTERR_00532   GGHTERR_00534
GGHTERR_00533   GGHTERR_00535
GGHTERR_00776   GGHTERR_00779
GGHTERR_01220   GGHTERR_01620
GGHTERR_01760   GGHTERR_01761
GGHTERR_01774   GGHTERR_02404
GGHTERR_01889   GGHTERR_01890
GGHTERR_02081   GGHTERR_02287
GGHTERR_02152   GGHTERR_02153
GGHTERR_02260   GGHTERR_02321
GGHTERR_02295   GGHTERR_02375
GGHTERR_02419   GGHTERR_02437
GGHTERR_02420   GGHTERR_02438
GGHTERR_02430   GGHTERR_02448
GGHTERR_00001
GGHTERR_00002
GGHTERR_00003
GGHTERR_00004
GGHTERR_00005
GGHTERR_00006
GGHTERR_00007

3列、2列、1列の行数を簡単に計算する方法があるかどうかを知りたいです。

したがって、出力は次のようになります。

3 columns: 3
2 columns: 14
1 colums: 7

ベストアンサー1

Awkはこれに最適です。スペースで行を分割し(デフォルトではoptionsに変更-F)、内部変数NF(フィールド数)には1行あたりのフィールド数があります。したがって、ファイルを見て、NF各行を保存します。

awk '{ 
        nums[NF]++
     }
     END{
        for(num in nums){
            printf "%d columns: %d\n", num, nums[num]
        }
     }' file

上記のコードは単にNFフィールド数()を連想配列に格納します。numsここで、キーはフィールド数、値はファイル内の列番号が見つかった回数です。最後に、配列を繰り返し印刷します。上記の例を実行すると、次の結果が得られます。

$ awk '{ nums[NF]++}END{for(num in nums){printf "%d columns: %d\n", num, nums[num]}}' file
1 columns: 7
2 columns: 14
3 columns: 3

このアプローチの1つの(マイナーな)欠点は、ファイルの各行のエントリをメモリに保持する必要があることです。ファイルが非常に大きい場合、または利用可能なメモリがほとんどない場合は問題ありません。ただし、その場合は、1行あたりのフィールド数を印刷して計算して問題を解決できます。

$ awk '{ print NF}' file | sort | uniq -c
      7 1
     14 2
      3 3

または、同じ出力を得るには、次のようにします。

$ awk '{ print NF}' file | sort | uniq -c | while read num fields; do printf "%d columns: %d\n" "$num" "$fields"; done
7 columns: 1
14 columns: 2
3 columns: 3

おすすめ記事