Bash : remplacer des chaines par d'autres ans un fichier
Résolu
mortelrdv
-
mortelrdv -
mortelrdv -
Bonjour,
je suis SunOS ajamei1u1 5.10 Generic_147441-01 i86pc i386 i86pc
j'ai un fichierA contenant une liste de chaines à remplacer par d'autres dans un fichierB.
fichierA
et donc en gros je veux remplacer dans le fichierB :
aaa -----> bbbbb
ddd -----> zzz
hhh -----> kkk
je suis SunOS ajamei1u1 5.10 Generic_147441-01 i86pc i386 i86pc
j'ai un fichierA contenant une liste de chaines à remplacer par d'autres dans un fichierB.
fichierA
aaa;bbbbb ddd;zzz hhh;kkk
et donc en gros je veux remplacer dans le fichierB :
aaa -----> bbbbb
ddd -----> zzz
hhh -----> kkk
je peux faire un truc du genre sed -i "s/aaa/bbbbb" fichierB au tant de fois (avec boucle) qu'il y a de ligne dans le fichierA (x fois ouverture/fermeture de fichierB, ça fait travailler le disque) il y a peut etre une meilleur solution (qui sait), Comment y prendriez vous ? Merci PS : sachant que le fichierA peut contenir plus de 300 lignes et que le fichierB peut contenir plus de 7000 lignes.
5 réponses
-
Déjà pour les remplacements de sed j'ajouterais un "/g" à la fin pour que toutes les occurrences d'un motif dans un ligne soient substituées. Ensuite la manière de rendre tout ça efficace, c'est d'enchaîner les sed à la volée (-e) via des pipes (|) au lieu de faire la modifications dans le fichier lui même (-i) :
(mando@silk) (~) $ cat toto.txt aaa;bbbb ddd;zzz hhh;kkk (mando@silk) (~) $ sed -e "s/bbbb/aaa/g" toto.txt | sed -e "s/ddd/zzz/g" | sed -e "s/hhh/kkk/g" > tata.txt (mando@silk) (~) $ cat tata.txt aaa;aaa zzz;zzz kkk;kkk
Bonne chance-
oui, mais là c'est un cas simple.
mais dans le cas où le fichierA contient plein de possibilité de remplacement, mettre tout ça sur une ligne de commande c'est invivable.
de plus je me vois mal de faire des lignes de sed de cette longueur à chaque fois que le contenu du fichierA change (on n'en finira plus avec les copier/coller :) )
-
-
Salut,
$ head fich* ==> fichA <== aaa;bbbbb ddd;zzz hhh;kkk ==> fichB <== aaa -----> bbbbb ddd -----> zzz hhh -----> kkk $ OIFS="${IFS}";IFS=";" while read cA cB do sed -i "s/${cA}/${cB}/g" fichB done < fichA IFS="${OIFS}" $ head fich* ==> fichA <== aaa;bbbbb ddd;zzz hhh;kkk ==> fichB <== bbbbb -----> bbbbb zzz -----> zzz kkk -----> kkk $
-
Ah tiens, je viens de faire un essai assez concluant ma foi ;-))
Plutôt que de s'embêter avec la variable ${IFS}, j'ai carrément pris la ligne dans sa totalité, mais par contre j'ai changé le séparateur par défaut de "sed", qui est le slash pour rappel, par celui contenu dans le fichA, à savoir le point virgule (;), et ça marche ;-))
$ while read line;do sed -i.bak "s;${line};g" fichB;done < fichA $ cat fichB bbbbb -----> bbbbb zzz -----> zzz kkk -----> kkk $
Enjoy ;-))
-
-
-
J'avais mal lu lors de ma première réponse, ci-dessous un script shell qui répond à la remarque :
https://forums.commentcamarche.net/forum/oldest/26751996-bash-remplacer-des-chaines-par-d-autres-ans-un-fichier#2
#!/bin/bash conf="subst.txt" in="toto.txt" out="titi.txt" cmd="cat $in" while read line do a="$(echo $line | cut -d';' -f1)" b="$(echo $line | cut -d';' -f2)" cmd="$cmd | sed -e \"s/$a/$b/g\"" done < $conf cmd="$cmd > $out" eval $cmd
... avec le fichier subst.txt qui contient :
aaa;bbbbb ddd;zzz hhh;kkk
... et toto.txt le fichier sur lequel on se base pour générer le fichier titi.txt.
Ceci dit, la solution https://forums.commentcamarche.net/forum/oldest/26751996-bash-remplacer-des-chaines-par-d-autres-ans-un-fichier#6 est plus concise :-)
Bonne chance -
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question -