一致する行を次の行にコピーして編集しますか?

一致する行を次の行にコピーして編集しますか?

次のファイルが与えられた場合:

a foo 1
b bar 2
c foo 3
d baz 4
e bar 5

ファイルを次のように変更したいと思います。結果が次のようになるように、次の行をbar含む各行をコピーして変更します。barbar2

a foo 1
b bar 2
b bar2 2
c foo 3
d baz 4
e bar 5
e bar2 5

答え1

Stéphaneが提案したようにp行を印刷してs置き換えると、sed結果は自動的に印刷されます。

sed '/bar/{p;s//&2/;}'  infile

答え2

awkを使用してください。

$ awk '1; sub(/bar/,"&2")' file
a foo 1
b bar 2
b bar2 2
c foo 3
d baz 4
e bar 5
e bar2 5

$ awk '1; sub(/bar/,"hello world")' file
a foo 1
b bar 2
b hello world 2
c foo 3
d baz 4
e bar 5
e hello world 5

この行を印刷します(1)それからあなたがbar望むものに置き換えようとし、成功すると(sub()ゼロ以外の値を返す)、今修正された行を再印刷します。

答え3

使用awk:

$ awk '/bar/{print; sub(/bar/,"&2")}1'

〜のように答えはsed示しています、このawkコマンドはprintスキーマでレコードを記録してbarからsubビルドしますbar2

答え4

使用幸せ(以前のPerl_6)

~$ raku -ne '.put; .put if s/bar/bar2/;'  file

または:

~$ raku -ne '.put; .subst(/bar/, "bar2").put if /bar/;'   file

または:

~$ raku -ne '.put; /bar/ && .subst(/bar/, "bar2").put;'   file

RakuはPerlファミリーのプログラミング言語です。組み込みのUnicodeの高度なサポートがあります。上記では、データをRaku(およびPerlの)テーマ変数-neに1行ずつロードする非自動印刷行別フラグが使用されました。$_Rakuはデフォルトで自動的に行を削除するのでput(代わりに)を呼び出すとprint改行文字が追加されます。putリントあなた歌う-ティーターミネーター)。

  • putRakuは/ printetcに明示的なオブジェクトを提供する必要があり、あいまいさを減らします。したがって、このような.put略語は、変更されていない行が印刷されることを意味します。$_.putput $_

  • 最初の例では、変更された行によく知られているs///代替記号が追加されています。 (s:g///ここではグローバル交換のため)。

  • 2 番目の例では、if検索一致がsubst発生し、結果行がput次の行に表示されます。 3番目の例は&&段落に依存することを除いて、2番目の例とほぼ同じです。

  • Rakuで一致が発生すると、通常、一致は変数$<>にロードされます(と同じです$/が読みやすい)。だから課題は「2を追加」これはまたS/bar/$<>2/はより簡単にを使用して行うことができます.subst(/bar/, "$<>2");

入力例:

a foo 1
b bar 2
c foo 3
d baz 4
e bar 5

出力例:

a foo 1
b bar 2
b bar2 2
c foo 3
d baz 4
e bar 5
e bar2 5

特に複雑な正規表現を使って作業する場合、上記の例はあまり乾燥しません。ただし、さらに使用するために、一致を一時変数に保存できます($a以下のように)。

~$ raku -ne '.put; if m/complicated_pattern/ -> $a {S/<$a>/replacement/.put};'  file

または、regex最初から-class変数を宣言します。

~$ raku -ne 'BEGIN my regex RE {complicated_pattern};  \
             .put; .put if s/<RE>/replacement/;  file

#OR

~$ raku -ne 'BEGIN my regex RE {complicated_pattern};  \
             .put; .subst(/<RE>/, "replacement" ).put if /<RE>/;'  file

#OR

~$ raku -ne 'BEGIN my regex RE {complicated_pattern};  \
             .put; /<RE>/ && put .subst(/<RE>/, "replacement" );'  file

https://docs.raku.org/type/Regex
https://raku.org

関連情報