行を複製し、sed を使用して複製を検索および置換するにはどうすればよいですか?

行を複製し、sed を使用して複製を検索および置換するにはどうすればよいですか?

特定の特殊文字を含むテキスト ファイルの行を複製しようとしていますが、複製では特殊文字を「通常の」ASCII 文字に置き換えます。具体的な使用例は、アクセント付き文字です。

入力:

éva
test
frédéric

望ましい出力:

éva
eva
test
frédéric
frederic

今のところ、文字を含む行を複製することはできますéが、キャプチャ グループ内で検索および置換する方法がわかりません。

これまでに得たものは次のとおりです。

echo 'éva\ntest\nfrédéric' | sed 's/\(.*é.*\)/&\n\1/'

でそれができますかsed?できない場合は、喜んで協力させていただきますawk...

答え1

複数のコマンドを一致させて適用することができますé:

sed '/é/{p;s/é/e/g;}'

を含む行についてはé、現在のパターン スペースを出力し、すべてéの を に置き換えますe(そして、パターン スペースを再度出力します)。

AWKの同等品は

awk '/é/{print; gsub(/é/, "e")}1'

sedsコマンドはアドレスパターンを再利用できます:

sed '/é/{p;s//e/g;}'

置換がすべて 1 文字の置換である場合、yコマンドはより効率的になります。

sed '/é/{p;y/é/e/;}'

答え2

$ awk '1; gsub(/é/,"e")' file
éva
eva
test
frédéric
frederic

上記では以下を使用します:

  1. 慣用的な true 条件は1、awk に現在の行を印刷するというデフォルトのアクションを実行させます。
  2. gsub()é任意のs を s に置き換えe、任意の s が見つかった/置き換えられた場合はé、条件コンテキストで正の戻り値が再度使用され、awk は現在の (現在変更されている) 行を印刷するというデフォルトのアクションを実行します。

からの戻りコードを使用して が見つかったgsub()かどうかを知らせることで、コマンド内でé同じ正規表現を 2 回指定する冗長性が回避されることに注意してください。/é/

答え3

さらにもう一つのsed選択肢 -@EdMorton のawk回答

sed -n 'p;s/é/e/gp' file

答え4

別のオプション、@Stephen Kitt に似ている:

$ sed '/é/p;s/é/e/g'
éva
eva
test
frédéric
frederic

  • /é/p文字がある行を選択してé印刷します。
  • s/é/e/g置換後の前の行を出力します。

関連情報