web-dev-qa-db-ja.com

grep出力を短い行に制限する

私はよくgrepを使用して、次のような特定のエントリを持つファイルを見つけます。

grep -R 'MyClassName'

良い点は、ファイルとその内容を返し、見つかった文字列を赤でマークすることです。悪い点は、テキスト全体が1つの大きな行に書き込まれる巨大なファイルもあることです。これらの大きなファイル内でテキストを検索すると、grepが大量に出力するようになりました。出力を、たとえば左右に5ワードに制限する方法はありますか?または、出力を左右30文字に制限することもできますか?

8
Socrates

grep自体には、行に基づくコンテキストのオプションのみがあります。 このSU投稿 で代替案が提案されています:

回避策は、オプション 'only-matching'を有効にしてから、RegExpのパワーを使用してテキストよりも少し多くgrepすることです。

grep -o ".\{0,50\}WHAT_I_M_SEARCHING.\{0,50\}" ./filepath

もちろん、色の強調表示を使用する場合は、常にgrepを実行して、実際の一致にのみ色を付けることができます。

grep -o ".\{0,50\}WHAT_I_M_SEARCHING.\{0,50\}"  ./filepath | grep "WHAT_I_M_SEARCHING"

別の選択肢として、 fold テキストを入力してからグレップすることをお勧めします。例えば:

fold -sw 80 input.txt | grep ...

-sオプションは、foldを作成し、単語を次の行に挿入します。

または、他の方法を使用して、入力の構造に基づいて入力を行に分割します。 (たとえば、SUの投稿はJSONを扱っていたため、jqなどを使用してpretty-printおよびgrep ...を使用するか、単にjqを使用して単独でフィルタリングを実行します...上記の2つの選択肢のいずれよりも優れています)


このGNU awkメソッドはより高速かもしれません:

gawk -v n=50 -v RS='MyClassName' '
  FNR > 1 { printf "%s: %s\n",FILENAME, p prt substr($0, 0, n)}
  {p = substr($0, length - n); prt = RT}
' input.txt
  • 関心のあるパターン(-v RS=...)とコンテキスト内の文字数(-v n=...)でレコードを分割するようにawkに指示する
  • 最初のレコード(FNR > 1)の後の各レコードは、awkがパターンに一致するものを見つけたものです。
  • したがって、前の行のn末尾の文字(p)と現在の行のnの先頭文字(substr($0, 0, n))を、前の行の一致テキスト(prt)とともに出力します。
    • pおよびprtafter印刷を設定するため、設定した値はnext
    • RTはGNUismであるため、これはGNU awk固有です。

再帰検索の場合:

find . -type f -exec gawk -v n=50 -v RS='MyClassName' 'FNR>1{printf "%s: %s\n",FILENAME, p prt substr($0, 0, n)} {p = substr($0, length-n); prt = RT}' {} +
15
muru

only-matchingを他のオプション(下記参照)と組み合わせて使用​​すると、他の答えで述べられている正規表現の処理オーバーヘッドなしで、探しているものに非常に近い場合があります

grep -RnHo 'MyClassName'
  • n数値出力、一致の行番号を表示
  • H filename、一致の行の先頭にファイル名を表示
  • o一致のみ、計算された文字列のみを表示し、行全体は表示しません
1
Robert Riedl