角かっこ間のテキストを置き換える

角かっこ間のテキストを置き換える

私はawk '{ gsub(/BAR|WIBBLE/, "FOO"); print }'次のデータのテキストを置き換えるために使用します。

SOMETHING [BAR, WIBBLE]
SOMETHING [BAR]

これにより、望ましい結果が得られます。

SOMETHING [FOO, FOO]
SOMETHING [FOO]

ただし、置き換える必要があるテキストを次のように更新する必要があります。

awk '{ gsub(/BAR|WIBBLE|ME/, "FOO"); print }'

これにより、テキストは次のように変更されます。

SOMETHING [ME, WIBBLE]

入力する:

SOFOOTHING [FOO, FOO]

角かっこ間のテキストにのみ置換を制限するにはどうすればよいですか(つまり、そのテキストを保持しますかSOMETHING?)

編集する

また、強力なテキストが必要ですSOMETHING(例:SHE GAVE ME THAT置き換えてはいけませんME)。

答え1

必ずそうでしょうかawk?代替の代替部分が関数呼び出しである可能性がある他の言語でははるかに簡単です。例えばperl:

perl -pe 'sub c{$s=shift;$s=~s/BAR|WIBBLE|ME/FOO/g;$s}s/\[.*?\]/c$&/ge' 

答え2

GNU awkを使用すると、角かっこの内容を設定してから(一致するレコード区切り文字)で置換を実行できますRSRT

awk -v RS='\\[[^]]*\\]' '{ gsub(/\<(BAR|WIBBLE|ME)\>/, "FOO", RT); printf "%s%s", $0, RT }' infile

入力ファイル:

cat << EOF > infile
SHE GAVE ME THAT
SOMETHING [ME, WIBBLE, SOMMER]
EOF

出力:

SHE GAVE ME THAT
SOMETHING [FOO, FOO, SOMMER]

答え3

awkには正規表現の置き換え時に逆参照が不足しているため、状況に応じて簡単に置き換えることはできません。 sedは次のことができます。

sed -e 's/\(\[[^]]*\)BAR/\1FOO/' 's/\(\[[^]]*\)ME/\1FOO/'

sed が正規表現の置換をサポートする場合:

sed -e 's/\(\[[^]]*\)\(BAR\|ME\)/\1FOO/'

サフィックスがあっても閉じられていない角かっこの最も長い順序が一致するため、g各括弧のペア内で単一の置換のみを処理します。[^]]*これらすべてを置き換えるには、明示的なループを使用します。これはorのサブストリングFOOではない場合にのみ機能します。BARME

sed -e ': a' -e 's/\(\[[^]]*\)BAR/\1FOO/' -e 't a' \
             -e 's/\(\[[^]]*\)ME/\1FOO/' -e 't a'

もっと複雑なものが必要な場合は、パールを使って

答え4

awk '{ gsub(/\bBAR\b|\bWIBBLE\b|\bME\b/, "FOO"); print }'

関連情報