Supponiamo di avere un file che contiene più occorrenze di StringA e StringB. Voglio sostituire tutte le occorrenze di StringA con StringB e (contemporaneamente) tutte le occorrenze di StringB con StringA.
In questo momento, sto facendo qualcosa come
cat file.txt | sed 's/StringB/StringC/g' | sed 's/StringA/StringB/g' | sed 's/StringC/StringA/g'
Il problema con questo approccio è che presuppone che StringC non si trovi nel file. Sebbene questo non sia un problema in pratica, questa soluzione sembra ancora sporca, ovvero sembra un'opportunità per imparare più magia unix. 🙂
Risposta accettata:
Se StringB
e StringA
non può apparire sulla stessa riga di input, quindi puoi dire a sed di eseguire la sostituzione in un modo e provare nell'altro solo se non ci sono occorrenze della prima stringa cercata.
<file.txt sed -e 's/StringA/StringB/g' -e t -e 's/StringB/StringA/g'
Nel caso generale, non credo che ci sia un metodo facile in sed. A proposito, nota che la specifica è ambigua se StringA
e StringB
possono sovrapporsi. Ecco una soluzione Perl, che sostituisce l'occorrenza più a sinistra di una delle due stringhe e si ripete.
<file.txt perl -pe 'BEGIN {%r = ("StringA" => "StringB", "StringB" => "StringA")}
s/(StringA|StringB)/$r{$1}/ge'
Se vuoi restare con gli strumenti POSIX, awk è la strada da percorrere. Awk non ha una primitiva per le sostituzioni parametrizzate generali, quindi è necessario eseguirne una propria.
<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
}'