StringAとStringBの両方が複数出現するファイルがあるとします。 StringAのすべての出現箇所をStringBに置き換え、(同時に)StringBのすべての出現箇所をStringAに置き換えたい。
今、私は次のようなことをしています
cat file.txt | sed 's/StringB/StringC/g' | sed 's/StringA/StringB/g' | sed 's/StringC/StringA/g'
このアプローチの問題は、ファイル内でStringCが発生しないことを前提としていることです。これは実際には問題ではありませんが、このソリューションはまだ汚い感じがします。つまり、UNIXの魔法をもっと学ぶ機会のように感じます。 🙂
承認された回答:
StringB
の場合 およびStringA
同じ入力行に表示できない場合は、sedに一方の方法で置換を実行し、最初に検索された文字列が発生しなかった場合にのみ、もう一方の方法を試すように指示できます。
<file.txt sed -e 's/StringA/StringB/g' -e t -e 's/StringB/StringA/g'
一般的に、sedには簡単な方法はないと思います。ちなみに、StringA
の場合、仕様があいまいであることに注意してください。 およびStringB
オーバーラップできます。これがPerlソリューションで、どちらかの文字列の左端のオカレンスを置き換えて繰り返します。
<file.txt perl -pe 'BEGIN {%r = ("StringA" => "StringB", "StringB" => "StringA")}
s/(StringA|StringB)/$r{$1}/ge'
POSIXツールを使い続けたい場合は、awkが最適です。 Awkには、一般的なパラメーター化された置換用のプリミティブがないため、独自にロールする必要があります。
<file.txt awk '{
while (match($0, /StringA|StringB/)) {
printf "%s", substr($0, 1, RSTART-1);
$0 = substr($0, RSTART);
printf "%s", /^StringA/ ? "StringB" : "StringA";
$0 = substr($0, 1+RLENGTH)
}
print
}'