Supposons que j'ai une chaîne 'abbc' et que je souhaite remplacer:
- ab -> bc
- bc -> ab
Si j'essaye deux remplacements, le résultat n'est pas ce que je veux:
echo 'abbc' | sed 's/ab/bc/g;s/bc/ab/g'
abab
Quelle commande sed puis-je utiliser pour remplacer comme ci-dessous?
echo abbc | sed SED_COMMAND
bcab
EDIT : En fait, le texte pourrait avoir plus de 2 modèles et je ne sais pas combien de remplacements j'aurai besoin. Puisqu'il y a eu une réponse disant qu'il sed
s'agit d'un éditeur de flux et que ses remplacements sont avidement, je pense que je devrai utiliser un langage de script pour cela.
g
drapeau de ces deuxs///
commandes et cela fonctionnera.ab
oubc
dans l'entrée d'origine.Réponses:
Peut-être quelque chose comme ça:
Remplacez-le
~
par un caractère dont vous savez qu'il ne figurera pas dans la chaîne.la source
\x0
pour~~
.g
nécessaire et que fait-il?g
est pour global - il remplace toutes les instances du modèle dans chaque ligne, au lieu de la première (qui est le comportement par défaut).J'utilise toujours plusieurs instructions avec "-e"
$ sed -e 's:AND:\n&:g' -e 's:GROUP BY:\n&:g' -e 's:UNION:\n&:g' -e 's:FROM:\n&:g' file > readable.sql
Cela ajoutera un «\ n» avant tous les AND, GROUP BY, UNION et FROM, tandis que «&» signifie la chaîne correspondante et «\ n &» signifie que vous souhaitez remplacer la chaîne correspondante par un «\ n» avant le «correspondant» "
la source
Voici une variante de la réponse d'ooga qui fonctionne pour plusieurs recherches et remplace les paires sans avoir à vérifier comment les valeurs peuvent être réutilisées:
Voici un exemple:
avant:
après:
Notez que cela
\b
dénote les limites des mots, ce qui empêche l'________
interférence avec la recherche (j'utilise GNU sed 4.2.2 sur Ubuntu). Si vous n'utilisez pas de recherche de limite de mot, cette technique peut ne pas fonctionner.Notez également que cela donne les mêmes résultats que la suppression de
s/________//g
et l'ajout&& sed -i 's/________//g' path_to_your_files/*.txt
à la fin de la commande, mais ne nécessite pas de spécifier le chemin deux fois.Une variation générale à ce sujet serait d'utiliser
\x0
ou_\x0_
de remplacer________
si vous savez qu'aucune valeur nulle n'apparaît dans vos fichiers, comme l'a suggéré jthill .la source
sed 's/ab/xy/' | sed 's/cd/ab/' .....
)sed
est un éditeur de flux. Il recherche et remplace goulûment. La seule façon de faire ce que vous avez demandé est d'utiliser un modèle de substitution intermédiaire et de le modifier à la fin.echo 'abcd' | sed -e 's/ab/xy/;s/cd/ab/;s/xy/cd/'
la source
Cela pourrait fonctionner pour vous (GNU sed):
Cela utilise une table de recherche qui est préparée et conservée dans l'espace d'attente (HS), puis ajoutée à chaque ligne. Un marqueur unique (dans ce cas
\n
) est ajouté au début de la ligne et utilisé comme méthode pour parcourir la recherche sur toute la longueur de la ligne. Une fois que le marqueur atteint la fin de la ligne, le processus est terminé et est imprimé la table de recherche et les marqueurs jetés.NB La table de recherche est préparée au tout début et un deuxième marqueur unique (dans ce cas
:
) choisi pour ne pas entrer en conflit avec les chaînes de substitution.Avec quelques commentaires:
Le tableau fonctionne comme ceci:
la source
Peut être une approche plus simple pour une occurrence de modèle unique, vous pouvez essayer comme ci-dessous: echo 'abbc' | sed 's / ab / bc /; s / bc / ab / 2'
Ma sortie:
Pour plusieurs occurrences de motif:
Exemple
J'espère que cela t'aides !!
la source
Tcl a une fonction intégrée pour cela
Cela fonctionne en parcourant la chaîne un caractère à la fois en faisant des comparaisons de chaînes à partir de la position actuelle.
En perl:
la source
Voici un
awk
basé sur les oogassed
la source