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
参照 https://stackoverflow.com/questions/5858200/sed-replace-every-nth-occurrence
ソリューションでは、sedではなくawkを使用しますが、「ジョブに適したツールを使用してください」。 可能であってもなくてもかまいませんが、そうであっても、lotで簡単になりますawkやPerlなどのツール。
sed 's/pattern/replacement/2'
パターンを持つすべての行の2番目のオカレンスを置き換えます。
GNU sed
がある場合:
sed '1~2N ; s/pattern/replacement/2'
1行目から始まる1
、パターンスペースに追加される後の行N
次に、s
コマンドは、パターンの2番目のオカレンスを置き換えます。次にsed
は2行下に移動します~2
と繰り返します。
簡単な解釈:
少なくとも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でも実行できると思いますが、かなりトリッキーであり、使用する正規表現に依存していると思います。何か解決して投稿してみますが、とりあえず、上記のシンプルなバージョンでこの答えを説明します。
あなたはとても近かったです、最初の行をスキップしてください:
sed '1n;s/pattern/replacement/;n'
この場合、なぜawk
が優れたツールになるのでしょうか?
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;}'