GNU/Linux >> Linux Esercitazione >  >> Linux

Scambia in modo pulito tutte le occorrenze di due stringhe usando Sed?

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

Linux
  1. Utilizzo di più modelli contemporaneamente con il comando Sed

  2. Corrispondenza di pattern multilinea utilizzando Sed, Awk o Grep?

  3. Utilizzando un riferimento a una variabile di stringa Bash in Sed?

  4. Usare Sed con personaggi speciali?

  5. Mostra tutto il file fino alla partita?

Come estendere lo spazio di scambio utilizzando il file di scambio in Linux

Quale processo sta utilizzando tutto il mio disco IO

Il modo più breve per scambiare due file in bash

Come unire due file usando AWK?

Utilizzo di sed per rimuovere un blocco di testo

sed - come creare gruppi regex usando sed