Plusieurs actions de recherche et de remplacement dans un grand fichier texte

11

J'ai un gros fichier texte (environ 2 Go). Je veux faire cinq actions de recherche et de remplacement sur le même fichier et je voudrais le faire en une seule commande. Normalement, j'utilise vim, j'ouvre le fichier, j'effectue une action de remplacement, puis la suivante, etc. Il y a un problème, car j'ai remarqué qu'après trois ou quatre recherches, vim se bloque à cause de problèmes de mémoire.

Voici deux exemples de la commande que j'utilise dans Vim:

:%s/www\.abcdef/www.test.abcdef/g 
:%s/www\.klmnop/www.test.klmnop/g

Quelle est la meilleure façon de gérer cela?

SPRBRN
la source

Réponses:

8

J'utiliserais sed comme ceci:

sed -i "s/www\.abcdef/www.test.abcdef/g;s/www\.kmlnop/www.test.klmnop/g;" yourfile.txt

-ioption signifie remplacement "sur place". Vous pouvez demander à sed de créer une sauvegarde de votre fichier en fournissant une extension à cette option ( -i.baksauvegardera yourfile.txt en tant que yourfile.txt.bak).

ssssteffff
la source
C'est rapide! Non seulement votre réponse ;-) mais ce script avec 5 recherches et remplacements est environ 10 fois plus rapide que l'ouverture du fichier dans vim. Une chose m'a cependant troublé. Au début, je pensais que le fichier .bak serait le fichier édité, mais c'est bien sûr l'original.
SPRBRN
Dix actions de recherche et de remplacement (avec des milliers de hits) dans un fichier de 2 Go en une seule fois, pas de problèmes de mémoire. Moins de deux minutes sur un bureau moyen - super!
SPRBRN
Une question ... Vous échappez aux points dans la chaîne de remplacement. Est-ce nécessaire?
SPRBRN du
1
Vous êtes les bienvenus @rxt :) En fait, vous avez raison, vous pouvez utiliser des points non échappés dans la chaîne de remplacement dans sed. J'ai essayé, et ça marche. Il y a un bon fil dans Unix et Linux Stackexchange , et la réponse acceptée ne mentionne pas les points comme caractères à échapper.
ssssteffff
2
@rxt vous avez dit remplacer la chaîne, désolé, non, vous n'avez pas besoin de les y échapper.
terdon
6

Si vous avez beaucoup plus de modèles de recherche, vous pouvez les enregistrer dans un fichier et en lire les substitutions. Par exemple, disons que c'est le contenu de replacements.txt:

www\.abcdef www.test.abcdef 
www\.klmnop www.test.klmnop

Vous pouvez ensuite lire une liste de N remplacements et les remplacer par ceci:

while read from to; do
  sed -i "s/$from/$to/" infile.txt ; 
done < replacements.txt 

REMARQUES:

  • Cela suppose que vos chaînes de recherche ne contiennent pas d'espaces et que tout caractère étrange doit être échappé replacements.txt.
  • Il en exécutera un sedpar remplacement, ce qui peut prendre un certain temps si vous avez de nombreuses opérations de remplacement.
  • Il peut traiter un nombre arbitraire de remplacements (des milliers ou des millions ou autre) tant que cela ne vous dérange pas que cela prendra un peu plus de temps.

Une autre option serait d'écrire ce qui précède sous forme de sedscript:

s/www\.abcdef/www\.test\.abcdef/g;
s/www\.kmlnop/www\.test\.klmnop/g;
s/aaaa/bbbb/g;
s/cccc/dddd/g;
s/eeee/ffff/g;

Vous pouvez ensuite exécuter le script sur votre fichier et il effectuera tous les remplacements en une seule fois:

sed -f replace.sed infile.txt 
terdon
la source
+1 pour ,, l'autre option ''. Cela pourrait être pratique d'avoir les remplacements stockés dans un fichier! (J'espère que je m'en souviendrai ...)
mpy
+1 pour l '"autre option" également parce qu'il utilise des fonctionnalités natives plutôt qu'un script personnalisé, il est donc plus portable / partageable
David Cook
@DavidCook merci, mais ce n'est pas plus natif ou portable que l'autre. La première approche utilise une boucle shell POSIX, elle est exactement aussi portable que la seconde. Ce sera juste beaucoup plus lent car il utilise une boucle shell.
terdon
Vous avez raison, ce que je voulais dire, c'est que le format de fichier de script sed est plus portable, car il utilise la fonctionnalité sed intégrée plutôt qu'un script, qui devrait être partagé avec le fichier replacements.txt. Néanmoins, ce sont deux excellentes options!
David Cook