web-dev-qa-db-ja.com

ディレクトリ内のすべてのファイルについて、列内の特定の値を持つ行数を再帰的にカウントします

ディレクトリに40個のファイルがあり、各ファイルの最初の列に「2」が付いた行がある回数を個別にカウントしたいと思います。

私はこのようなことを試みていますが、各ファイルから合計を出力し、個々の合計が必要です。

find . -type f -print0 | xargs -0 awk '($1=="2"){++count} END {print count}'

明確にするために、これは例です。

FILE_1

2   345     123     4
2   4567    2344    6
3   2345    657     87
6   234     345     6

FILE_2

1   12  436 7
2   54  86  8
2   23  48  0
2   098 0   8
8   98  9   0

印刷:

FILE_1 2
FILE_2 3

私が実際に得ているもの:

印刷:

5 

ご協力いただきありがとうございます!

3
Rebe

grepにカウントさせることができます。必要な行が2で始まると仮定すると、次を使用できます。

grep -c '^[[:space:]]*2\>' $(find . -type f -print0 | xargs -0 echo)

正規表現の最後にある\>は、一致が「単語の境界」で停止することを保証し、2ではなく20で始まる行などの誤警報を回避します。

注:

探している「40個のファイル」がすべて同じディレクトリ(サブディレクトリではない)にある場合は、findに現在のディレクトリを再帰せずにのみ検索させることができます(待ち時間を短縮するため)。そう:

find -maxdepth 1 . -type f -print0

更新:

2が最初の列とは異なる列にあるファイルを照合するには、次のようにします。

COLNUM=3
TOMATCH=$(($COLNUM-1))
grep -cE "^[[:space:]]*([0-9]+[[:space:]]+){$TOMATCH}2\>" \
$(find . -type f -print0 | xargs -0 echo)

必要に応じてCOLNUMを変更できます。基本的に、これは、Wordの境界でCOLNUM-1列とそれに続く2を一致させようとします。 -Eスイッチは、拡張正規表現を有効にするために必要です。これにより、{}表記を使用して数値量指定子を指定できます(つまり、「前のパターンと何度も一致する」)。

ただし、ファイルに存在しない列番号を入力すると、正規表現はサイレントに失敗することに注意してください。

4
Joseph R.

いくつかの解決策:

  1. awk-execオプションを使用して、各ファイルでfindを実行します。

    find . -type f \
    -exec awk '($1=="2"){++count}END{print FILENAME ": " count}' {} \;
    
  2. awk FNR変数を使用して、awkスクリプトのファイル変更を検出します。

    find . -type f -print0 | xargs -0 \
    awk 'FNR==1{if (NR!=1){print count} printf("%s: ", FILENAME);}($1=="2"){++count}END{print count}'
    
2
andcoz

出力を変更してもかまわない場合は、次の操作を実行できます。

$ grep "^2" *|awk '{print $1}'|uniq -c
      2 FILE_1:2
      3 FILE_2:2

PRINT出力が必要な場合:

$ grep "^2" *|awk '{print $1}'|uniq -c|sed 's/:2//'|awk '{print $2, $1}'
FILE_1 2
FILE_2 3
0
slm