Quel est un bon moyen de faire des remplacements de chaînes dans un fichier en utilisant un dictionnaire avec beaucoup de paires substituant-substituant ? Et par beaucoup , je veux dire en fait environ 20 - pas beaucoup, mais assez pour que je veuille les organiser soigneusement.
Je veux en quelque sorte collecter toutes les paires substituant-substituant dans un fichier dictionary.txt
d'une manière facile à gérer, puisque j'ai besoin de remplacer beaucoup de choses, dites comme :
"yes" : "no"
"stop" : "go, go, go!"
"wee-ooo" : "ooooh nooo!"
"gooodbye" : "hello"
"high" : "low"
"why?" : "i don't know"
Maintenant, je veux appliquer ces substitutions dans un fichier novel.txt
.
Ensuite, je veux exécuter magiccommand --magicflags dictionary.txt novel.txt
de sorte que toutes les instances de yes
dans novel.txt
sont remplacés par no
(donc même Bayesian
serait remplacé par Banoian
) et toutes les instances de goodbye
dans novel.txt
serait remplacé par hello
et ainsi de suite.
Jusqu'à présent, les chaînes que je dois remplacer (et remplacer par) ne le font pas contenir des guillemets (ni simples ni doubles). (Ce serait bien, cependant, de voir une solution fonctionner correctement avec des chaînes contenant des guillemets, bien sûr.)
Je connais sed
et awk
/ gawk
peuvent faire ce genre de choses principalement, mais peuvent-ils également travailler avec de tels fichiers de dictionnaire ? Ressemble à gawk
serait le bon candidat pour magiccommand
, quels sont les bons magicflags
? Comment dois-je formater mon dictionary.txt
?
Réponse acceptée :
Voici une façon avec sed
:
sed '
s|"(.*)"[[:blank:]]*:[[:blank:]]*"(.*)"|1
2|
h
s|.*n||
s|[&/]|\&|g
x
s|n.*||
s|[[.*^$/]|\&|g
G
s|(.*)n(.*)|s/1/2/g|
' dictionary.txt | sed -f - novel.txt
Comment ça marche :
Le 1er sed
transforme dictionary.txt
dans un fichier de script (commandes d'édition, une par ligne). Ceci est redirigé vers le 2ème sed
(notez le -f -
ce qui signifie lire les commandes de stdin
) qui exécute ces commandes, en éditant novel.txt
.
Cela nécessite de traduire votre format
"STRING" : "REPLACEMENT"
dans un sed
commande et en échappant tous les caractères spéciaux dans le processus pour les deux LHS
et RHS
:
s/ESCAPED_STRING/ESCAPED_REPLACEMENT/g
Donc la première substitution
s|"(.*)"[[:blank:]]*:[[:blank:]]*"(.*)"|1
2|
transforme "STRING" : "REPLACEMENT"
dans STRINGnREPLACEMENT
(n
est un caractère de saut de ligne). Le résultat est ensuite copié sur le h
ancien espace.s|.*n||
supprime la première partie en ne gardant que REPLACEMENT
puis s|[&/]|\&|g
échappe les caractères réservés (c'est le RHS
).
Il ex
change le tampon de maintien avec l'espace de motif et s|n.*||
supprime la deuxième partie en ne gardant que STRING
et s|[[.*^$/]|\&|g
fait l'échappement (c'est le LHS
).
Le contenu du tampon de maintien est ensuite ajouté à l'espace de modèle via G
donc maintenant le contenu de l'espace de modèle est ESCAPED_STRINGnESCAPED_REPLACEMENT
.
Le remplacement final
s|(.*)n(.*)|s/1/2/g|
le transforme en s/ESCAPED_STRING/ESCAPED_REPLACEMENT/g