perl を使用してコマンド ラインで迅速な解決策を探している場合、これはflip-flop
オペレーターにとって理想的なケースです。さて、この質問を極端なケースで解釈できる方法は 2 つありpattern1
ますpattern2
。
パターン1がパターン2 の後、パターン 3 の前にある場合、パターン 1とパターン3 の間のすべてを削除します
または、pattern1がpattern2の後、pattern3 の前にある場合、別のpattern1が表示されない限り何もしません。
始める前に、perl の引数に注意してください-p
-n assume "while (<>) { ... }" loop around program
-p assume loop like -n but print line also, like sed
さて、最初に、私はあなたに..
perl -pe'$x ||= /7/; $_= "" if /5/ .. /8/ and $x' <(seq 1 10)
1
2
3
4
5
6
9
10
$x ||= /7/
:のとき$x
の戻り値に設定します。一致すると戻ります。これは、最初の一致で true に設定されることを意味し、その性質上、変数が既に true になっている場合は設定されません。/7/
$x
false
/7/
true
$x
||=
次に$_ = ''
、範囲が と の間/5/
にあり/8/
、すでに$x
true に設定されている場合に設定します。短絡が機能する方法を覚えておいてください:と評価される場合にのみa && b
実行することを意味します。この場合、単に評価するという事実だけで、フリップフロップ演算子の状態が設定されます。これが私たちが望んでいることです。ただし、既に表示されている場合にのみ発生させたいと考えています。b
a
true
a
$_ = ''
7
さて、質問の 2 番目の解釈では、順序を入れ替えてください...
perl -pe'$x ||= /7/; $_= "" if $x and /5/ .. /8/' <(seq 1 10)
これにより、全範囲が出力されます。Perl は/5/
、 が見つかるまで検索を開始しません/7/
。私たちのシーケンシャル範囲では、それは起こりません。
ところで、これらの回答のいくつかを恥ずべきことにするために、スペースの多くは必要ありません...
perl -pe'$x||=/2/;$_=""if$x&&/5/../8/' # secksey