sedでカッコで囲まれた部分のみ、任意の文字を一括置換したい(シェル)

Bash

はじめに

タイトルで説明しにくいのが辛い(-_-;)

teratail で面白い質問がありました。

僕も常々 sed でこれを実現できないものか?と思っていたので、とても参考になりました。

検証環境

$ sed --version | head -n 1
sed (GNU sed) 4.7

やりたいこと

以下のような文字列があるとします。

私は、いろいろな国(日本、中国、韓国)に行ったことがあります。

これを以下のように置換したいです。

私は、いろいろな国(日本|中国|韓国)に行ったことがあります。

カッコの中の だけを | に置換したいわけです。

seds 内部コマンドだけではなかなかつらい

ぱっと思いつくのが sed 's/、/|/g' ですね。

$ echo '私は、いろいろな国(日本、中国、韓国)に行ったことがあります。' \
  | sed 's/、/|/g'
私は|いろいろな国(日本|中国|韓国)に行ったことがあります。

これだとカッコの外部分も置換されてしまいます。

$ echo '私は、いろいろな国(日本、中国、韓国)に行ったことがあります。' \
  | sed 's/(\([^、)]*\)、\([^)]*\))/(\1|\2\)/g'
私は、いろいろな国(日本|中国、韓国)に行ったことがあります。

これだと、複数の が置換できません。

seds 内部コマンドといくつかの内部コマンドを組み合わせると実現できる

q 内部コマンドと t 内部コマンドを組み合わせると、標準出力から受け取った文字列に s 内部コマンドの置換処理が適用できなくなるまで処理を繰り返すことができます。

$ echo '私は、いろいろな国(日本、中国、韓国)に行ったことがあります。' \
  | sed ':q; s/(\([^、)]*\)、\([^)]*\))/(\1|\2)/g; t q'
私は、いろいろな国(日本|中国|韓国)に行ったことがあります。

ひとこと

大変勉強になりました。
回答者の方、Linux関連の回答で総合1位なんですね。すごい。

Bash