改行を無視してファイル内のテキストを検索する方法は?


11

ファイル内の複数行に分割されている可能性のあるテキストを検索したいのですが。改行を無視し、一致する行のスパンを返すgrep。

例えば、私はを検索していてis an example file、それが次のファイルにあることを期待しています:

これは、 サンプルファイル。

先頭または末尾のスペースに依存しないようにするには、すべての形式の空白を完全に無視するのが最適です(理想的には、一連の空白を単一のスペースとして扱う)。


非理想的な解決策の1つはtr '\n' ' ' | grep、一致と非一致を区別しますが、一致を表示せず、大きなファイルを適切に処理しません。


SO(決定的な回答なし):stackoverflow.com/q/1858312/1449460
Nikana Reklawyks

isearch-forward
ちなみに

Vimも同様です/This\_sis。詳細::help \_s
lcd047

この行を検索行の最後に追加します。tr -n "\ n"これにより、すべての新しい行が削除されます。この助けを願っています!
ダンハウエル2017

回答:


12

GNU grepができる

grep -z 'is\san\sexample\sfile.' file

コメントで発生するいくつかのポイントを満たすために、スクリプトにいくつかの変更があります。

 grep -oz '^[^\n]*\bis\s*an\s*example\s*file\.[^\n]*' file

巨大なファイルに関しては、私はメモリ制限の想像力はありませんが、問題が発生した場合は自由に使用できます sed

sed '/\bis\b/{
          :1
          N
          /file\.\|\(\n.*\)\{3\}/!b1
         }
     /\<is\s*an\s*example\s*file\./p
     D' file

メモリ内に4行以下(パターンでは4ワード)を保持します(\(\n.*\)\{3\})。


5
ご存知のとおり、この-zオプションはgrep改行を通常のテキスト文字として扱い、nulバイトを探してレコードを分離するように指示します。nulバイトのないテキストファイル(つまり、一般的なケース)では、grep -zファイル全体を1行として扱います。したがって、(1)これにより、大きなファイルをどれだけ適切に処理できるかという問題が発生します。(2)一致が見つかった場合、ファイル全体が書き出され、一致の場所についての手がかりは得られません。また、(3)OPは「理想的には、一連の空白を1つのスペースとして扱う」と述べたため、を使用\s+して追加する必要があり-Eます。
G-Manは「Reinstate Monica」を

1
@ G-Manコメントありがとうございます。編集した回答をご覧ください。
コスタ

1
(0)ああ、-o; 私はそれを忘れ続けます。それを使う賢い方法。(1)新しいgrep答えが始まり^[\n]*ます。それはのタイプミスです[^\n]*。② \s+意図的に言った。  be\s*littleと一致しbelittle、とcare\s*less一致しcarelessます。しかし、それは小さな問題だと思います。また、を使用したくない-E場合は、の「貧乏人版」\s+、つまりを使用できます\s\s*。(3)素晴らしいsedコマンド。空白行があると失敗する可能性があります(そのため、4語句は4行を超える場合があります)。これを追加することで修正できましたs/\n\s*\n/\n/
G-Manが「Reinstate Monica」を

@ G-Manありがとうございましたg。あなたのコメントはとても役に立ちます。有名なメンバーが毎回私にそうするように勧めるので、私は多かれ少なかれ移植可能なコードを投稿しようとしています。とにかくさえせずに-E使用することができます鋼+\s\+フォーム。パターンの内側の空の線は不自然なようです。
Costas

RFCのようなページ付けされたテキストドキュメントを考えていました—一部のシステムではmanページがそのように見えるISTR(またはそうでした)— (s)grepフレーズを希望する前に、それを取り除く必要があります。
G-Manが「Reinstate Monica」を

7

これを試して:

pcregrep -M '\bThis\s+is\b' <<EOT
This
is
an example
file.
EOT

私は入力する必要があります\s、私は「これは非常に長いパターンである」で検索した場合に5回?
Nikana Reklawyks

1
はい:ポイントは\sスペースに一致し、改行は「スペース」です。
lcd047

つまり、ファイルがThis\nis a very\nlong patternであり、改行が発生する可能性がある場所がわからない場合。私は検索する必要がThis\sis\sa\svery\slong\spatternありますよね?(パターンの長さが増加するか、他の場所から貼り付けられると、退屈になります)
Nikana Reklawyks

2
次に、次のようにしますpcregrep -M "$( echo 'This is a very long pattern' | sed 's/ /\\s+/g' )" file
lcd047
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.