ほとんどの場合はより良いかもしれませんが、ファイルが本当に大きく、sed
そのような大きなスクリプトファイル(スクリプトの約5000行以上で発生する可能性がある)を処理できない場合に備えて、ここでは単純sed
です:
sed -ne:t -e"/\n.*$match/D" \
-e'$!N;//D;/'"$match/{" \
-e"s/\n/&/$A;t" \
-e'$q;bt' -e\} \
-e's/\n/&/'"$B;tP" \
-e'$!bt' -e:P -e'P;D'
これは、入力時のスライディングウィンドウと呼ばれるものの例です。これは、何かを印刷しようとする前に、-count行の先読みバッファーを$B
作成することで機能します。
実際、おそらく、以前のポイントを明確にする必要があります。このソリューションの主なパフォーマンスリミッターは、間隔に直接関連します。このソリューションは、間隔サイズが大きいと遅くなりますが、間隔周波数が大きいとドンは遅くなります。言い換えれば、入力ファイルが非常に大きい場合でも、実際の間隔の発生が依然として非常にまれである場合、彼の解決策がおそらく道です。ただし、間隔サイズが比較的管理しやすく、頻繁に発生する可能性がある場合は、これが選択すべきソリューションです。
ワークフローは次のとおりです。
- 場合
$match
によって先行パターンスペースで発見され\n
ewline、sed
再帰的になりD
、すべてのelete \n
ewlineその先行して。
$match
以前はパターンのスペースを完全に消去していましたが、オーバーラップを簡単に処理するために、ランドマークを残しておくとはるかにうまくいくようです。
- また
s/.*\n.*\($match\)/\1/
、一度に取得してループをかわそうとしました$A/$B
が、大きい場合は、D
エレテループの方がかなり高速です。
- 次に
N
、\n
ewlineデリミタが前にある入力のext行をD
取得し、/\n.*$match/
最後に使用した正規表現w /を参照してもう一度エレテを選択しようとします//
。
- パターンスペースが一致する場合、行の先頭で
$match
のみ一致することができます。以前の行は$match
すべて$B
クリアされています。
- そこで、
$A
fterをループし始めます。
- このループの各実行は、我々がしようとします
s///
ためubstitute &
自体$A
番目の\n
パターンスペースでewline文字を、そして、成功した場合、t
当社全体および- ESTたちを分岐する$A
完全に上からかけてスクリプトを起動するためのスクリプトの実行- FTERバッファを次の入力行がある場合。
t
estが成功しなかった場合、opラベルにb
戻って:t
別の入力行を再帰します。fterの$match
収集中にループオーバーが発生する可能性があり$A
ます。
- 私たちが乗り越える場合
$match
、機能ループ、そして我々はしようとするでしょうp
RINT $
場合、これはそれをされた場合、最後の行をし、!
しようとしないs///
ためubstitute &
自体$B
番目の\n
パターンスペースでewline文字を。
- 我々はよ
t
、それが成功した場合、EST、この、あまりにも、私たちはに分岐するでしょう:P
RINTラベル。
- そうでない場合は、
:t
opに戻って、バッファーに追加された別の入力行を取得します。
- 我々はそれがために作る場合
:P
RINT我々はよP
その後、RINT D
最初までelete \n
パターンスペースにewlineとどのような遺跡でトップからスクリプトを再実行します。
それで、今回は A=2 B=2 match=5; seq 5 | sed...
:P
rint での最初の反復のパターンスペースは次のようになります。
^1\n2\n3$
そして、それsed
はその$B
前のバッファを収集する方法です。そして、収集した入力の後ろのsed
出力$B
-count行に出力します。この前の例与えられた、ということでしょうRINT を出力し、[ eleteこととのように見えるスクリプトパターンスペースの上部に送り返すには:sed
P
1
D
^2\n3$
...そして、スクリプトの上部でN
ext入力行が取得されるため、次の反復は次のようになります。
^2\n3\n4$
したがって5
、入力で最初の出現を見つけると、パターン空間は実際には次のようになります。
^3\n4\n5$
次に、D
エレテループが開始され、終了すると次のようになります。
^5$
そして、N
ext入力行がプルされるsed
と、EOFにヒットして終了します。その時までに、P
ライン1と2 のみをリントしました。
実行例を次に示します。
A=8 B=7 match='[24689]0'
seq 100 |
sed -ne:t -e"/\n.*$match/D" \
-e'$!N;//D;/'"$match/{" \
-e"s/\n/&/$A;t" \
-e'$q;bt' -e\} \
-e's/\n/&/'"$B;tP" \
-e'$!bt' -e:P -e'P;D'
それは印刷します:
1
2
3
4
5
6
7
8
9
10
11
12
29
30
31
32
49
50
51
52
69
70
71
72
99
100