500行のテキストを含むファイルがあるとします。
one
two
three
four
five
six
seven
eight
nine
ten
.
.
.
five-hundred
一致後に5行目を特定の文字列に置き換えるには、次の手順を実行します。
sed '/two/{n;n;n;n;n;s/.*/MODIFIED/}' inputfile
出力:
one
two
three
four
five
six
MODIFIED
eight
nine
ten
.
.
.
five-hundred
しかし、試合が終わった後に60番のラインを交換したい場合はどうすればいいですか?私は「n」を60回書きたくありません。
x、h / H、g / G、および範囲を試してみましたが、まだ希望の出力を得ることはできません。
答え1
解決策awk
:
awk '/two/{ n=NR+5 } NR==n{ sub(/.*/, "MODIFIED") }1' file
または路線を変更したい場合
awk '/two/{ n=NR+5 } NR==n{ $0="MODIFIED" }1' file
答え2
これらの操作では、検索パターンがオフセットの前に再表示される場合は、どうすればよいかを検討する必要があります。
awk -v offset=60 '
/two/ {x[NR + offset]}
NR in x {delete x[NR]; $0 = "MODIFIED"}
{print}'
上記の60行が含まれるたびに、ラインの交換が保証されますtwo
。
答え3
/two/{
:loop
N
/\(\(.*\n\)\{5\}\).*/{
s//\1Modified/
b
}
b loop
}
保存x.sed
して次のように実行します。
sed -f x.sed file
またはGNU Sedを使用する1行のコード:
sed '/two/{:a;N;/\(\(.*\n\)\{5\}\).*/{s//\1Modified/;b;};ba;}' file
ライン別分析:
- 1-2:一致するものが見つかったら繰り返しを開始します。このサイクルでは
- 3:コマンドを使用してパターンスペースに行を追加します
N
。 - 4:5つの改行がある場合(デフォルトの正規表現は
\(.*\n\)\{5\}
-)、キャプチャグループに入れ、最後の行(.*
)をキャプチャされていません。- 5: 全体のパターン空間*をキャプチャグループに置き換え、その後に
Modified
行を追加します。 - 6: サイクルを壊しなさい。
- 5: 全体のパターン空間*をキャプチャグループに置き換え、その後に
- 8: 言い換えてください
loop
。
- 3:コマンドを使用してパターンスペースに行を追加します
*空の正規表現スロットは、以前に使用された正規表現と同じなので、5行目はと同じですs/\(\(.*\n\)\{5\}\).*/\1Modified/
。
あまり難解ではないのはAwkを使うことです。
awk '{c--};/two/{c=5};c==0{$0="Modified"};{print}' file
最初の値は減少するカウンターc
で、すべての変数はc
最初にゼロであるため、一致する項目が見つかった場合にのみ正の値になります。
より明示的なアプローチは次のとおりです。
awk 'BEGIN{c=-1};/two/{c=5};c==0{$0="Modified"};{print};c>=0{c=c-1}' file
便利なSedリソース:
答え4
すべてのUnixシステムのすべてのシェルでawkを使用して、これらの一致が5行の範囲内で繰り返し発生しないと仮定し、完全な行文字列一致を実行します。
$ awk 'c&&!--c{$0="MODIFIED"} $0=="two"{c=5} 1' file
one
two
three
four
five
six
MODIFIED
eight
nine
ten
.
.
.
five-hundred