Je souhaite exclure le fichier ./test/main.cpp
de ma recherche.
Voici ce que je vois:
$ grep -r pattern --exclude=./test/main.cpp
./test/main.cpp:pattern
./lib/main.cpp:pattern
./src/main.cpp:pattern
Je sais qu'il est possible d'obtenir la sortie que je veux en utilisant plusieurs commandes dans un arrangement de tuyaux et de filtres, mais y a-t-il des citations / échappements qui feront grep
comprendre ce que je veux en natif?
command-line
grep
nobar
la source
la source
--exclude-dir
). C'est pourquoi je voudrais que grep effectue nativement l'exclusion.Réponses:
grep
ne peut pas faire cela pour un fichier dans un certain répertoire si vous avez plus de fichiers du même nom dans différents répertoires, utilisez plutôt find:find . -type f \! -path './test/main.cpp' -exec grep pattern {} \+
la source
\!
et\+
? Il semble fonctionner correctement sans les contre-obliques.grep
ne peut pas faire cela, utilisezfind
plutôt" - parfait.Je ne pense pas que ce soit possible avec GNU
grep
. Mais vous n'avez pas besoin de tuyaux.Avec
find
:Avec
zsh
:(exclut les fichiers cachés, tout aussi bien pour exclure les .git, .svn ...).
la source
Je pourrais écrire un livre: "L'art perdu de
xargs
". Lefind ... -exec … ';
lance un grep pour chaque fichier (mais pas la variante avec-exec … +
). Eh bien, nous perdons des cycles CPU ces jours-ci, alors pourquoi pas, non? Mais si les performances, la mémoire et l'alimentation sont un problème: utilisez xargs:De GNU
find
« s de-print0
seNUL
-terminate sa production etxargs
» les-0
honneurs options que le format en entrée. Cela garantit que quels que soient les personnages amusants de votre fichier, le pipeline ne sera pas confondu. L'-r
option s'assure qu'il n'y a pas d'erreur au cas oùfind
rien ne serait trouvé.Remarque, vous pouvez maintenant faire des choses comme:
GNU grep
-z
fait la même chose que xargs-0
.la source
find -exec (cmd) {} +
fonctionne de la même manière quexargs
etfind -exec (cmd) {} \;
fonctionne de la même manière quexargs -n1
. En d'autres termes, votre déclaration n'est correcte que si la\;
version est utilisée.xargs
est moins efficace que l'utilisation-exec … +
(quoique marginalement). Aucune des réponses ici ne mentionne même-exec … \;
.-exec ... +
ajouté en janvier 2005. Ouais, je ne suis pas obsolète ... du tout.Si vos
find
supports-path
ont été ajoutés à POSIX en 2008 mais manquent toujours dans Solaris:la source
-path
pas POSIX?Pour mémoire, voici l'approche que je préfère:
En gardant le
grep
au début de la commande, je pense que c'est un peu plus clair - en plus cela ne désactive pasgrep
la surbrillance des couleurs. Dans un sens, l'utilisationfind
dans une substitution de commande n'est qu'un moyen d'étendre / remplacer le sous-ensemble (limité) de recherche de fichiers degrep
la fonctionnalité de.Pour moi, la
find -exec
syntaxe est un peu mystérieuse. Une complexité avecfind -exec
est le besoin (parfois) d'échapper à divers caractères (notamment si\;
est utilisé sous Bash). Juste pour mettre des choses dans des contextes familiers, les deux commandes suivantes sont fondamentalement équivalentes:Si vous souhaitez exclure des sous - répertoires , il peut être nécessaire d'utiliser un caractère générique. Je ne comprends pas complètement le schéma ici - parlez des arcanes :
Une autre note pour généraliser les
find
solutions basées sur l'utilisation dans les scripts : Lagrep
ligne de commande doit inclure l' option-H
/--with-filename
. Sinon, cela modifiera la mise en forme de la sortie dans le cas où il se trouve qu'il n'y a qu'un seul nom de fichier dans les résultats de la recherchefind
. Ceci est remarquable car il ne semble pas nécessaire si vous utilisezgrep
la recherche de fichiers native de (avec l'-r
option).... Encore mieux, cependant, est d'inclure
/dev/null
comme premier fichier à rechercher. Cela résout deux problèmes:grep
pense qu'il y en a deux et utilise le mode de sortie à fichiers multiples.grep
pensera qu'il y a un fichier et ne se bloque pas en attente sur stdin.La réponse finale est donc:
la source
find
dans une substitution de commande. Cela se casse s'il existe des noms de fichiers contenant des espaces ou d'autres caractères spéciaux. Utilisationfind -exec
, il est robuste et facile à utiliser.find -iname "*target*" -or -name 'exclude' -prune
. Eh bien, cela fonctionne en quelque sorte - le répertoire élagué sera répertorié, mais pas recherché. Si vous ne voulez pas qu'il soit répertorié, vous pouvez ajouter une sorte de redondance! -name 'exclude'