例えば
xyz
A1
B1
C1
D1
End
End
End
X1
X2
X3
Done
xyzから終了パターンまでのすべての文字列を抽出したいと思います。したがって、出力は次のようになります
xyz
A1
B1
C1
D1
End
End
End
答え1
方法1
perl -l -0777ne 'print /^(xyz.*?^End$(?:\nEnd$)*)/ms' yourfile
布材
- ファイルは1つの長い文字列として表示されるように読み取られ、その後適切な正規表現を使用して分割できます。この例の正規表現は次のとおりです。
- 行の先頭でxyzを探します(必ずしもファイルである必要はありません)。
- 一行だけで最も近い端を見つけ、できるだけ多くの連続行を探します。
方法2
perl -lne '
next unless /xyz/ ... eof;
last if !/End/ and $flag;
$flag ||= 1 if /End/;
print;
' yourfile
布材
- ここでは、ラインごとにPerlを操作し、小さなステートマシンを設定します。
- ファイルの範囲外の部分を拒否します。
- 正しい範囲を入力すると、/ End /行に達するまですべての行が印刷されます。それから私たちは標識を立てました。
- その後、/End/ではなく最初の行を見ると爆発します。
方法3
sed -e '
/xyz/!d
:a
$q;N
/\nEnd$/!ba
:b
n
/End/bb
d
' yourfile
この方法では、/xyz/から/End/までの行を累積する最初のdo-whileループ(:a)が機能します。
2番目のdo-whileループ(:b)は、次の行が/ End /になるまで行を印刷します。
方法4
sed -e '
/xyz/,/End/!d
H;/xyz/h;/End/!d
:a
$q;N
/\(.*\)\n\1$/!{g;q;}
s/.*\n//;H
ba
' yourfile
このアプローチを使用して、まず正しい範囲を選択してから、その範囲データを記憶領域に保存します。 do-whileループ(:a)は、予約されたスペースに徐々に追加されるように設定されており、次の行は/ End /です。
結果
xyz
A1
B1
C1
D1
End
End
End
答え2
このpcregrep
仕事は次のことをうまく行います。
pcregrep -M 'xyz(.|\n)*End' file
欲が多いので最後まで食べませんのでご注意ください終わり、その他を含む終わりS.
答え3
Perlが助けます。xyz
最初の行と最後の行の間のすべての行を印刷しますEnd
。
perl -ne '
$inside = 1 if /^xyz$/;
$seen_end = 1 if $inside && /^End$/;
push @buff, $_ if $inside;
print splice @buff if /^End$/ && @buff;
' input-file
最初の発生から始めて、xyz
すべての行をバッファにプッシュし始めます。一度End
発生したら、バッファを出力して消去します(参照接合End
)、しかし後で別の行が表示される場合に備えて、行をバッファにプッシュし続けます。
答え4
アッ解決策:
awk '/xyz/,/End/{ print $0; n=NR }($0=="End" && n && NR>n && NR-n++ == 1)' file
出力:
xyz
A1
B1
C1
D1
End
End
End
/xyz/,/End/
- 記録範囲、xyz
からEnd
n=NR
- キャプチャレコード番号(範囲一致時 - 最終的に範囲を含める最後のレコードの番号)