GNU/Linux >> Tutoriels Linux >  >> Linux

Échangez proprement toutes les occurrences de deux chaînes à l'aide de Sed ?

Supposons que j'ai un fichier contenant plusieurs occurrences de StringA et StringB. Je souhaite remplacer toutes les occurrences de StringA par StringB et (simultanément) toutes les occurrences de StringB par StringA.

En ce moment, je fais quelque chose comme

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

Le problème avec cette approche est qu'elle suppose que StringC n'apparaît pas dans le fichier. Bien que ce ne soit pas un problème dans la pratique, cette solution semble toujours sale - c'est-à-dire qu'elle ressemble à une opportunité d'apprendre plus de magie Unix. 🙂

Réponse acceptée :

Si StringB et StringA ne peut pas apparaître sur la même ligne d'entrée, vous pouvez indiquer à sed d'effectuer le remplacement dans un sens, et n'essayer dans l'autre sens que s'il n'y avait aucune occurrence de la première chaîne recherchée.

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

Dans le cas général, je ne pense pas qu'il existe une méthode facile dans sed. Au fait, notez que la spécification est ambiguë si StringA et StringB peuvent se chevaucher. Voici une solution Perl, qui remplace l'occurrence la plus à gauche de l'une ou l'autre des chaînes, et se répète.

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

Si vous voulez vous en tenir aux outils POSIX, awk est la voie à suivre. Awk n'a pas de primitive pour les remplacements paramétriques généraux, vous devez donc créer la vôtre.

<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. Utilisation de plusieurs modèles à la fois avec la commande Sed

  2. Utilisation d'une référence à une variable de chaîne Bash dans Sed ?

  3. Utiliser Sed avec des caractères spéciaux ?

  4. Fournir deux arguments à une option à l'aide de Getops ?

  5. Enregistrer le fichier après avoir utilisé la commande Sed ?

Comment étendre l'espace d'échange à l'aide du fichier d'échange sous Linux

Supprimer tous les commentaires C avec Sed ?

Afficher tout le fichier jusqu'au match ?

sed débutant :modification de toutes les occurrences d'un dossier

Comment fusionner deux fichiers avec AWK ?

Supprimer un caractère spécifique en utilisant awk ou sed