Comment puis-je utiliser grep pour rechercher plusieurs répertoires non imbriqués?


21

Il peut sembler que je pose la même chose que cette question , mais j'ai des exigences différentes. Voici un exemple de mon système de fichiers:

  • /code/
    • interne/
      • dev /
      • principale/
    • Publique/
      • dev /
      • principale/
      • Libération/
    • outils/

/code/internal/dev/, /code/public/dev/Et /code/tools/contenir des sous - répertoires pour plusieurs projets. Je travaille presque exclusivement dans les branches de développement de /code/internal/et /code/public/, et souvent je veux rechercher une chaîne de texte dans ces répertoires avec /code/tools/(qui n'a pas de branches). Dans ces cas, je dois exécuter trois commandes distinctes:

$ grep -r "some string" /code/internal/dev/
$ grep -r "some string" /code/public/dev/
$ grep -r "some string" /code/tools/

Je voudrais savoir s'il existe une seule commande pour ce faire. Sinon, j'aurais probablement besoin d'écrire un simple script bash.

Réponses:


38

Vous pouvez concaténer plusieurs chemins à rechercher par grep:

grep -r "some string" /code/internal/dev/ /code/public/dev/ /code/tools/

C'est tellement évident. Pourquoi n'y ai-je pas pensé?!
David Kennedy

En fait, cela génère une erreur, grep: /code/internal/dev/*.cs: No such file or directorysauf si je supprime le *.csde la commande. C'est ma faute parce que j'ai posé *.csma question à l'origine.
David Kennedy

14

Si vous souhaitez utiliser au maximum les caractères génériques (et que la hiérarchie que vous avez publiée est complète), vous pouvez le faire

grep -r "some string" /code/{*/dev,tools}/*.cs

Explication:

La première étape effectuée est l'expansion de la liste contreventée. foo{bar,baz}quxse développe à foobarqux foobazqux. Autrement dit, il y a un mot distinct généré pour chaque élément séparé par des virgules dans la liste, avec la partie préfixe et postfixe attachée à chacun. Vous pouvez voir comment cela fonctionne en faisant

echo A{1,2,3,4}B

qui sort

A1B A2B A3B A4B

Notez que cela fonctionne également avec plusieurs accolades et également avec des arguments vides; par exemple

echo {,1,2}{0,1,2}:{2,3}

donne

0:2 0:3 1:2 1:3 2:2 2:3 10:2 10:3 11:2 11:3 12:2 12:3 20:2 20:3 21:2 21:3 22:2 22:3

Donc, après l'expansion de l'accolade, votre commande ressemble à ceci:

grep -r "some string" /code/*/dev/*.cs /code/tools/*.cs

L'étape suivante est l'expansion des caractères génériques. Vous le savez déjà pour la *.cspartie, mais cela fonctionne aussi pour les répertoires intermédiaires; de plus, si a /suit, seuls les répertoires sont mis en correspondance. Par conséquent, étant donné votre hiérarchie (et la création de noms de .csfichiers pour les fichiers), vous obtiendrez la commande:

grep -r "some string" /code/internal/dev/file1.cs /code/internal/dev/file2.cs /code/public/dev/file3.cs /code/tools/file4.cs /code/tools/file5.cs

Ce n'est qu'après que tout cela s'est produit, grepest appelé avec cette liste d'arguments (notez que la même chose se produit avec vos commandes d'origine; grepne voit jamais le *; l'expansion qui est complètement effectuée bashavant d'appeler grep).

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.