Question Comment faire une recherche récursive / remplacement d'une chaîne avec awk ou sed?


Comment puis-je trouver et remplacer chaque occurrence de:

subdomainA.example.com

avec

subdomainB.example.com

dans chaque fichier texte sous la /home/www/ arborescence de répertoires récursive?


522
2017-10-17 21:10


origine


Réponses:


Remarque: N'exécutez pas cette commande sur un dossier incluant un repo git - les modifications apportées à .git pourraient corrompre votre index git.

find /home/www -type f -print0 | xargs -0 sed -i 's/subdomainA\.example\.com/subdomainB.example.com/g'

De man find:

-print0   (GNU find only) indique à find d'utiliser le caractère nul (\ 0) au lieu de l'espace comme délimiteur de sortie entre les chemins trouvés. C'est une option plus sûre si vos fichiers peuvent contenir des espaces ou d'autres caractères spéciaux. Il est recommandé d'utiliser l'argument -print0 pour savoir si vous utilisez la commande -exec ou xargs (l'argument -0 est nécessaire dans xargs.).


701
2017-10-17 21:32



Remarque: N'exécutez pas cette commande sur un dossier incluant un repo git - les modifications apportées à .git pourraient corrompre votre index git.

find /home/www/ -type f -exec \
    sed -i 's/subdomainA\.example\.com/subdomainB.example.com/g' {} +

Comparé à d'autres réponses ici, c'est plus simple que la plupart des autres et utilise sed au lieu de perl, ce qui est ce que la question originale demandait.


209
2017-10-18 19:34



Le moyen le plus simple pour moi est

grep -rl oldtext . | xargs sed -i 's/oldtext/newtext/g'

63
2018-03-13 17:05



Toutes les astuces sont presque les mêmes, mais j'aime bien celle-ci:

find <mydir> -type f -exec sed -i 's/<string1>/<string2>/g' {} +
  • find <mydir>: recherchez dans le répertoire.

  • -type f:

    Le fichier est de type: fichier régulier

  • -exec command {} +:

    Cette variante de l'action -exec exécute la commande spécifiée sur les fichiers sélectionnés, mais la ligne de commande est créée en ajoutant             chaque nom de fichier sélectionné à la fin; le nombre total d'invocations de la commande sera beaucoup moins que le nombre de             fichiers correspondants. La ligne de commande est construite de la même manière que xargs construit ses lignes de commande. Une seule instance de             `{} 'est autorisé dans la commande. La commande est exécutée dans le répertoire de départ.


54
2018-01-31 12:00



cd /home/www && find . -type f -print0 |
  xargs -0 perl -i.bak -pe 's/subdomainA\.example\.com/subdomainB.example.com/g'

39
2017-10-17 21:13



Pour moi, la solution la plus simple à retenir est https://stackoverflow.com/a/2113224/565525, c'est à dire.:

sed -i '' -e 's/subdomainA/subdomainB/g' $(find /home/www/ -type f)

REMARQUE: -i '' résout le problème d'OSX sed: 1: "...": invalid command code .

REMARQUE: S'il y a trop de fichiers à traiter, vous obtiendrez Argument list too long. La solution de contournement - utiliser find -exec ou xargs solution décrite ci-dessus.


25
2017-09-03 10:00



Pour quiconque utilise Chercheur d'argent (ag)

ag SearchString -l0 | xargs -0 sed -i 's/SearchString/Replacement/g'

Comme ag ignore par défaut les fichiers / dossiers git / hg / svn, il est possible de les exécuter en toute sécurité dans un référentiel.


18
2017-09-02 05:19



Pour réduire les fichiers à récursivement sed à travers, vous pourriez grep pour votre instance de chaîne:

grep -rl <oldstring> /path/to/folder | xargs sed -i s^<oldstring>^<newstring>^g

Si vous courez man grep vous remarquerez que vous pouvez également définir un --exlude-dir="*.git" flag si vous voulez omettre de chercher dans les répertoires .git, en évitant les problèmes d'index git comme d'autres l'ont poliment souligné.

Vous menant à:

grep -rl --exclude-dir="*.git" <oldstring> /path/to/folder | xargs sed -i s^<oldstring>^<newstring>^g

15
2017-08-22 20:28



Un bon oneliner en extra. Utiliser git grep

git grep -lz 'subdomainA.example.com' | xargs -0 perl -i'' -pE "s/subdomainA.example.com/subdomainB.example.com/g"

12
2018-02-10 19:07



Celui-ci est compatible avec les dépôts git, et un peu plus simple:

Linux:

git grep -l 'original_text' | xargs sed -i 's/original_text/new_text/g'

Mac:

git grep -l 'original_text' | xargs sed -i '' -e 's/original_text/new_text/g'

(Grâce à http://blog.jasonmeridth.com/posts/use-git-grep-to-replace-strings-in-files-in-your-git-repository/)


11
2018-06-24 08:26