GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Alle Vorkommen von zwei Strings mit Sed sauber vertauschen?

Angenommen, ich habe eine Datei, die mehrere Vorkommen von StringA und StringB enthält. Ich möchte alle Vorkommen von StringA durch StringB und (gleichzeitig) alle Vorkommen von StringB durch StringA ersetzen.

Im Moment mache ich so etwas wie

cat file.txt | sed 's/StringB/StringC/g' | sed 's/StringA/StringB/g' | sed 's/StringC/StringA/g'

Das Problem bei diesem Ansatz ist, dass davon ausgegangen wird, dass StringC nicht in der Datei vorkommt. Obwohl dies in der Praxis kein Problem darstellt, fühlt sich diese Lösung immer noch schmutzig an – das heißt, sie fühlt sich wie eine Gelegenheit an, mehr Unix-Magie zu lernen. 🙂

Akzeptierte Antwort:

Wenn StringB und StringA nicht in derselben Eingabezeile erscheinen kann, dann können Sie sed anweisen, die Ersetzung auf eine Weise durchzuführen und es nur auf die andere Weise zu versuchen, wenn die erste gesuchte Zeichenfolge nicht vorkommt.

<file.txt sed -e 's/StringA/StringB/g' -e t -e 's/StringB/StringA/g'

Im Allgemeinen glaube ich nicht, dass es in sed eine einfache Methode gibt. Beachten Sie übrigens, dass die Angabe mehrdeutig ist, wenn StringA und StringB überlappen können. Hier ist eine Perl-Lösung, die das ganz linke Vorkommen einer der beiden Zeichenfolgen ersetzt und wiederholt.

<file.txt perl -pe 'BEGIN {%r = ("StringA" => "StringB", "StringB" => "StringA")}
                    s/(StringA|StringB)/$r{$1}/ge'

Wenn Sie bei POSIX-Tools bleiben möchten, ist awk der richtige Weg. Awk hat kein Primitiv für allgemeine parametrisierte Ersetzungen, also müssen Sie Ihre eigenen rollen.

<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. Mehrzeiliger Musterabgleich mit Sed, Awk oder Grep?

  2. Alle C-Kommentare mit Sed löschen?

  3. Sed mit Sonderzeichen verwenden?

  4. Alle Dateien bis zum Match anzeigen?

  5. Welcher Prozess verwendet alle meine Festplatten-E / A

So erweitern Sie den Auslagerungsbereich mithilfe der Auslagerungsdatei in Linux

Geben Sie zwei Argumente für eine Option mit Getopts an?

Datei nach Verwendung des Sed-Befehls speichern?

sed Anfänger:Alle Vorkommen in einem Ordner ändern

Entferne ein bestimmtes Zeichen mit awk oder sed

sed - wie man Regex-Gruppen mit sed erstellt