同じ行にまたがっていても複数行にかかわらず、「start_」の最初の発生と「_end」の最初の発生の間のテキストを取得したいとします。一致を含めないでください。
テキスト例1:
This is a start_text with start_and some_end text with_end
出力テキスト1:
text with start_and some
テキスト例2:
This is a
start_text with
start_and some_end
text with_end
出力テキスト2:
text with
start_and some
私は多くの答えを見ましたが、それはすべてファイル中心ではなく行動中心です。コンソールベースなら、どんな種類のツールやコマンドでも可能です。
答え1
そしてperl
:
$ perl -l -0777ne 'print $1 while /start_(.*?)_end/gs' your-example-2
text with
start_and some
perl -n
各実行にsed -n
提供される式のパターンです。e
ワイヤーなどの入力sed
。-l
ingl
時に自動的に新しいineを追加することです。print
-<octal-number>
改行ではなく、指定された値を使用してレコード区切り文字をバイトに設定します。0777
(511)または0377(255)以上の値は存在できないバイト値であるため、ファイル全体と呼ばれるレコードは1つだけ残ります。*?
like は*
0 個以上の先行原子 (.
ここでは任意の単一文字) と一致しますが、while は*
できるだけ多くの原子と*?
できるだけ少ない数に一致するため、最後ではなく.*?
最初の発生まで実行されます。_end
s
改行文字を一致させるには、パターン一致演算子のフラグも/regexp/
必要.
ですが、デフォルトでは一致しません。
あなたもそれを使用できるはずですpcregrep
が、私はそれが提供していることを発見しました(Debianバージョン8.39 2016-06-14):
$ pcregrep -Mo1 '(?s)start_(.*?)_end' your-example-2
text with
start_and some
and some
私はそれを説明できません。pcre2grep
(バージョン 10.42 2022-12-11) ただし、次のことができます。
$ pcre2grep -Mo1 '(?s)start_(.*?)_end' your-example-2
text with
start_and some
1 技術的に保存する前に、レコード区切り文字が入力から削除されます。$_
そして出力レコード区切り記号($\
)は入力レコード区切り記号()と同じに設定され、入力レコード区切り文字はこの時点でまだ改行文字であるため、出力レコード区切り文字がに設定されていることが$/
重要です。与えられたバイト値なので。-l
-0...
-l<octal>
-l -<octal>