Utiliser sed et grep pour rechercher et remplacer
j'utilise egrep -R suivi d'une expression régulière contenant environ 10 syndicats, ainsi comme:
.jpg | .png | .gif etc. Cela fonctionne bien, maintenant je voudrais remplacer toutes les cordes trouvées par .bmp
je pensais à quelque chose comme
egrep -lR ".jpg|.png|.gif" . | sed "s/some_expression/.jpg/" file_it_came_form
donc la question ici est de savoir comment je fais une expression régulière syndicale similaire dans sed et comment je lui dis de sauvegarder les modifications dans le fichier à partir duquel il a obtenu les entrées.
6 réponses
utilisez cette commande:
egrep -lRZ "\.jpg|\.png|\.gif" . \
| xargs -0 -l sed -i -e 's/\.jpg\|\.gif\|\.png/.bmp/g'
-
egrep: trouver des lignes de correspondance en utilisant des expressions régulières étendues-
-l: seule liste correspondant aux noms de fichiers -
-R: rechercher récursivement dans tous les répertoires donnés -
-Z: utilisation"151950920"comme séparateur d'enregistrement -
"\.jpg|\.png|\.gif": correspondre à l'une des chaînes".jpg",".gif"ou".png" -
.: commencez la recherche dans le répertoire courant
-
-
xargs: exécuter une commande avec l'argument stdin-
-0: utiliser"151950920"comme séparateur d'enregistrement. Ceci est important pour correspondre au-Zdeegrepet pour éviter d'être dupé par les espaces et les nouvelles lignes dans les noms de fichiers d'entrée. -
-l: utilisez une ligne par commande comme paramètre
-
-
sed: le s tream ed itor-
-i: remplacer le fichier d'entrée par la sortie sans faire une sauvegarde -
-e: utilisez l'argument suivant comme expression -
's/\.jpg\|\.gif\|\.png/.bmp/g': remplacer toutes les occurrences des cordes".jpg",".gif"ou".png"par".bmp"
-
honnêtement, bien que j'aime sed pour les tâches appropriées, c'est certainement une tâche pour perl -- c'est vraiment plus puissant pour ce genre de monocouches, surtout pour "l'écrire à l'endroit d'où il vient" (le commutateur -i de perl le fait pour vous, et vous permet aussi optionnellement de garder l'ancienne version autour par exemple avec un .bak ajouté, il suffit d'utiliser -i.bak à la place).
perl -i.bak -pe 's/\.jpg|\.png|\.gif/.jpg/
plutôt que des travaux compliqués dans sed (si même possible là) ou awk...
une autre façon de le faire
find . -name *.xml -exec sed -i "s/4.6.0-SNAPSHOT/5.0.0-SNAPSHOT/" {} \;
un peu d'aide concernant la commande ci-dessus
la recherche fera la recherche pour vous dans l'annuaire courant indiqué par .
-name le nom du fichier dans mon cas, ses pom.xml peut donner des jokers.
-exec exécuter
sed éditeur de flux
-i ignorer affaire 1519100920"
s pour remplacer
/4.6.0.../ chaîne de caractères à rechercher
/5.0.0.../ chaîne à remplacer
Je ne pouvais pas faire fonctionner aucune des commandes sur cette page pour moi: le solution sed a ajouté une nouvelle ligne à la fin de tous les fichiers qu'il a traités, et le solution perl n'a pas été en mesure d'accepter assez d'arguments de find. J'ai trouvé cette solution qui fonctionne parfaitement:
find . -type f -name '*.[hm]' -print0
| xargs -0 perl -pi -e 's/search_regex/replacement_string/g'
cela va revenir dans l'arborescence courante du répertoire et remplacer search_regex par replacement_string dans tous les fichiers se terminant par .h ou .m .
j'ai également utilisé rpl à cette fin dans le passé.
essayez quelque chose à l'aide d'une boucle for
for i in `egrep -lR "YOURSEARCH" .` ; do echo $i; sed 's/f/k/' <$i >/tmp/`basename $i`; mv /tmp/`basename $i` $i; done
pas joli, mais ça devrait.
mon étui était je voulais remplacer
foo:/Drive_Letter avec foo:/bar/baz/xyz
Dans mon cas, j'ai pu le faire avec le code suivant.
J'étais dans le même répertoire où il y avait beaucoup de fichiers.
find . -name "*.library" -print0 | xargs -0 sed -i '' -e 's/foo:\/Drive_Letter:/foo:\/bar\/baz\/xyz/g'
espère que cela a aidé.
mise à jour s/foo:|Drive_letter:/foo:/ba/baz|xyz / g