段落/行を含む「abc.txt」ファイルがあるとします。
Hello, how are you doing sir?
when are you going to arrive at the SBAHN platform to catch the train?
ファイルから「どのように」から「キャッチ」までのすべての文字を抽出するには?
答え1
PCREをサポートするバージョンがある場合は、grep
次のコマンドを使用して必要な操作を実行できます。
$ grep -Pzo 'how.*\n.*catch' file
how are you doing sir?
when are you going to arrive at the SBAHN platform to catch
スイッチ:
-P
- できるようにするPCRE - Perl互換正規表現-z
- 通常、ファイル名に続く文字の代わりに0バイト(ASCII NUL文字)を出力します。たとえば、grep -lZ
通常の改行ではなく、各ファイル名の後にゼロバイトを出力します。このオプションを使用すると、ファイル名に改行などの珍しい文字が含まれていても出力が明確になります。このオプションはfind -print0, perl -0
、sort -z
などのコマンドと一緒に使用して、xargs -0
任意のファイル名、改行文字を含むファイル名も処理できます。-o
- 一致する行の一致する(空でない)部分のみを印刷し、各部分は別々の出力行に表示します。
答え2
作業に適したツールは次のとおりです。pcregrep
pcregrep -oM "how(.|\n)*catch" SPEC
pcregrep
:Perl互換正規表現を使用してgrepします。-o
:パターンに一致する線分のみ表示-M
: パターンが複数行に一致することを許可する(.|\n)*
:すべての文字または改行文字と0回以上一致します。
貪欲ではないバージョンが必要な場合は、?
以下を追加してください*
。
pcregrep -oM "how(.|\n)*?catch" SPEC
答え3
使用sed
この回答では、長い行を処理するための良い品質があると仮定しますsed
。テキストが次のファイルにあるとしますfile
。
$ tr '\n' '\001' <file | sed -n -r 's/.*(how.*catch).*/\1\n/p' | tr '\001' '\n'
how are you doing sir?
when are you going to arrive at the SBAHN platform to catch
説明する:
tr '\n' '\001' <file
これにより、ファイルから読み取られ、
file
すべての改行文字が8進数の001文字に置き換えられます。これは入力を単一ラインに変換する効果があります。sed -n -r 's/.*(how.*catch).*/\1\n/p'
これで入力が1行なので、
sed
これを簡単に処理できます。上記の置換コマンドは、「how」から「catch」までのすべてのテキストをキャプチャして標準出力に印刷します。このオプションを使用すると、
-n
正規表現が一致しない場合は何も印刷されません。したがって、入力にシーケンスがない場合はhow.*catch
何も印刷されません。tr '\001' '\n'
これにより、8進数の001文字が改行文字に変換されます。
sed
8進数001は、(a)入力ファイルにないことを確認し、(b)正しく処理できる文字に置き換えることができます。
使用awk
$ awk '/how/{f=1;sub(/.*how/,"how")} /catch/{f=0;sub(/catch.*/,"catch");print} f' file
how are you doing sir?
when are you going to arrive at the SBAHN platform to catch
説明する:
/how/{f=1;sub(/.*how/,"how")}
行に「how」という単語が含まれている場合、「how」の前のすべてのテキストが削除され、フラグ変数が
f
1に設定されます。/catch/{f=0;sub(/catch.*/,"catch");print}
行に「catch」という単語が含まれている場合、「catch」の後のすべてのテキストが削除され、フラグ変数が
f
0に設定され、変更された行が印刷されます。f
フラグが1の場合、このやや不思議なawkコマンドはその行を印刷します。この場合、
f==0
何も印刷されません。
答え4
sed
テキストがファイルの一部ではない場合、例は失敗し、何もない代わりに完全なファイルを取得します。
sedの代わりにgrepを使用してください。
tr '\n' '\001' < file | grep -o -E 'how.*catch' | tr '\001' '\n'
貪欲的マッチングと非貪欲的マッチングも問題であるため、「catch」が2行目にあり、別の「catch」が5行目にある場合は、非欲望的マッチングが必要です。
これを達成する方法についてはこちらをご覧ください。バージョンによって大きく異なりますgrep
。