web-dev-qa-db-ja.com

Sed:2番目の改行ごとにパターンを置き換えますか?

sedに2回目ごとにパターンを置き換えるように指示する方法はありますか?または、少なくとも1行おきに? (確かにスクリプトで可能ですが、sedがそれを実行できるかどうか自分に尋ねていました)。

編集

見つけた

sed -e "s/pattern/replacement/g;n"

しかし、それは2回目ではなく、最初の発生ごとに置き換えられました。

入力ファイル:

I have a pattern in each line
Also the second line has the pattern
Another pattern here
And -- you guess it -- a pattern

望ましい出力:

I have a pattern in each line
Also the second line has the replacement
Another pattern here
And -- you guess it -- a replacement
10

参照 https://stackoverflow.com/questions/5858200/sed-replace-every-nth-occurrence

ソリューションでは、sedではなくawkを使用しますが、「ジョブに適したツールを使用してください」。 可能であってもなくてもかまいませんが、そうであっても、lotで簡単になりますawkやPerlなどのツール。

6
cas
sed 's/pattern/replacement/2'

パターンを持つすべての行の2番目のオカレンスを置き換えます。


GNU sedがある場合:

sed '1~2N ; s/pattern/replacement/2'

1行目から始まる1、パターンスペースに追加される後の行N次に、sコマンドは、パターンの2番目のオカレンスを置き換えます。次にsedは2行下に移動します~2と繰り返します。

14
llua

簡単な解釈:

少なくとも1つのPATTERNのオカレンスを含む最初の行では、それを無視して、その行をそのまま印刷します。 PATTERNの少なくとも1つのオカレンスを含む2行目で、PATTERNの最初のインスタンスをREPLACEMENTに置き換えます。少なくとも1つのPATTERNのオカレンスを含む3行目に、その行をそのまま印刷します。 PATTERNの少なくとも1つのオカレンスを含む4行目で、PATTERNの最初のインスタンスをREPLACEMENTに置き換えます。等々。 PATTERNに一致しない行は変更せずに印刷する必要があります。

これは、Sedで簡単に行うことができます。

sed -e '/PATTERN/ { :inside' -e 'n;s//REPLACEMENT/;t' -e 'b inside' -e '}'

または、空白が少なくラベルが短い場合:

sed -e '/PATTERN/{:i' -e 'n;s//REPLACEMENT/;t' -e 'b i' -e '}'

編集:私は質問をもう一度読んで、より難しい解釈を見つけました:

ドキュメント全体で2番目に出現するPATTERNを、最初の出現と同じ行にあるかどうかにかかわらず、REPLACEMENTに置き換えます。最初と3番目のオカレンスは変更しません。等。

これはSedでも実行できると思いますが、かなりトリッキーであり、使用する正規表現に依存していると思います。何か解決して投稿してみますが、とりあえず、上記のシンプルなバージョンでこの答えを説明します。

2
Wildcard

あなたはとても近かったです、最初の行をスキップしてください:

sed '1n;s/pattern/replacement/;n'

この場合、なぜawkが優れたツールになるのでしょうか?

1
Philippos

1行内の1つのシンボルパターン:sed 's /(a [^ a] *)a/\ 1c/g'

1秒ごとのパターン(1行に1つのパターンマッチのみが表示されます。1行に2つ以上のマッチが表示される場合、2番目のパターンのみが置き換えられます)

echo -e "test\nreplace_me\ntest\ntest\nreplace_me\nreplace_me\nreplace_me" | \
sed '/replace_me/{:a;N;/replace_me.*replace_me/!Ta;s/replace_me/replaced/2;}'
0
rush