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-Z
deegrep
et 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