GNU/Linux >> Tutoriels Linux >  >> Linux

Remplacement de chaîne à l'aide d'un dictionnaire ?

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


Linux
  1. Comment écrire une chaîne de plusieurs lignes en utilisant Bash avec des variables ?

  2. Utilisation de grep pour rechercher une chaîne contenant un point

  3. Rediriger toutes les sorties vers un fichier à l'aide de Bash sous Linux ?

  4. comment restreindre la longueur de la chaîne présente dans une ligne en utilisant Linux

  5. Comment envoyer une chaîne au serveur en utilisant s_client

Comment créer une instance RDS à l'aide de Python Boto3 sur AWS

Utilisation de la commande Diff pour comparer deux fichiers dans un terminal Linux

Bash Beginner Series #4 :Utiliser des tableaux dans Bash

Utilisation de la commande Bash printf pour imprimer des sorties formatées

Utilisation de sed pour diviser une chaîne avec un délimiteur

Utilisation de scp pour transférer une liste de fichiers .txt