再帰 grep は特定の行番号のみ一致します。

再帰 grep は特定の行番号のみ一致します。

特定のパターンを含むファイルを見つける方法特定の行番号に? 3行のテキストファイルを含むディレクトリがあるとします。たとえば、次のようになります。

Title A
Category X
Description Y

Category Xすべてのオンラインファイルをgrep /フィルタリングする方法は2Title Aas行を含むファイルをどのように見つけることができますか1

grepのマニュアルページ、ripgrep、および代替案を見てきましたが、パターン検索を特定の行番号に制限することが可能かどうかはわかりません。

答え1

次のように使用できますawk

awk 'FNR == 2 && /Category X/ {print FILENAME}' *

答え2

with を使用すると、find2行目でパターンが見つかったときにawkファイルの残りの部分の処理を中断したり、2 行目パターンが見つからなかった場合に終了できます。

find -type f -name 'xyz*.txt' -exec \
    awk 'NR==2{ if(/pattern/) print FILENANE; exit }' {} \;

答え3

grep楽しみとして:

PAT="Category X"
LN=2
> grep -n "$PAT" file* | grep ":$LN:$PAT$" | grep -o "^[^:]*"
file1
file2

答え4

ユースケースにGNU grepを使用できます。

$ grep -Plzr '^(?:.*\n){1}.*Category X' .

grep通常、行単位で動作しますが、GNU grepは-zテキストファイルに見つからない文字()\0でレコードを区切るため、ファイル全体を1行として処理するオプションを追加します。

これで、ファイル全体に正規表現を適用できます。あなたの要件は2行目だけを検索することであるため、何もせずに1行を通過して航海します。^(?:.*\n){1}

キャレット^は正規表現を先頭に固定します。ポイントは改行文字と一致しないため、1行に渡ることはできません。

その後、検索は.*Category X次の行、つまり2行目から始まりますが、行を横切って移動しないため、2行目でパターンが見つかった場合は一致します。

一致するものがある場合、この-lオプションはファイル名をSTDOUTにリストします。

この-rオプションを使用すると、grepが再帰的に実行されます(GNU機能)。

-PPerlスタイルの正規表現(GNU機能)を作成できます。


GNU find + sedの組み合わせを使用して問題を解決する別の方法は次のとおりです。

$ find . -type f -exec sed -ns '2{/Category X/F;}' {} +

GNU find + GNU xargs 同じ操作を行うには、Perl と入力します。

find . -type f ! -size 0 -print0 |
xargs -r0 perl -lne '
  (eof||$.==2)&&do{
    print $ARGV if $.==2 && /Category X/;
    close  ARGV; undef $.;
  };
'

関連情報