GNU/Linux >> Linux の 問題 >  >> Linux

Sedを使用して2つの文字列のすべてのオカレンスをきれいに交換しますか?

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
}'

Linux
  1. Sed、Awk、またはGrepを使用したマルチラインパターンマッチ?

  2. SedですべてのCコメントを削除しますか?

  3. Getoptsを使用して1つのオプションに2つの引数を提供しますか?

  1. Sedコマンドで一度に複数のパターンを使用する

  2. SedでBash文字列変数への参照を使用しますか?

  3. Sedコマンドを使用した後にファイルを保存しますか?

  1. 特殊文字でSedを使用していますか?

  2. 一致するまですべてのファイルを表示しますか?

  3. すべてのディスク IO を使用しているプロセス