Une de mes commandes BASH préférées est:
find . -name '*.*' -exec grep 'SearchString' {} /dev/null \;
qui recherche le contenu spécifié de SearchString dans le contenu de tous les fichiers situés dans et sous le répertoire en cours. En tant que développeur, cela s’est parfois révélé utile.
Cependant, en raison de mon projet actuel et de la structure de ma base de code, j'aimerais rendre cette commande BASH encore plus évoluée en ne recherchant aucun fichier se trouvant dans ou sous un répertoire contenant ".svn", ni aucun fichier contenant un fichier. se termine par ".html"
La page MAN for find m'a un peu déroutée. J'ai essayé d'utiliser -Prune, et cela m'a donné un comportement étrange. En essayant de ne sauter que les pages .html (pour commencer), j'ai essayé:
find . -wholename './*.html' -Prune -exec grep 'SearchString' {} /dev/null \;
et n'a pas eu le comportement que j'espérais. Je pense que je pourrais manquer le point de -Prune. Pourriez-vous m'aider?
Merci
Vous pouvez utiliser la fonction negate (!) De find pour ne pas faire correspondre les fichiers portant des noms spécifiques:
find . ! -name '*.html' ! -path '*.svn*' -exec grep 'SearchString' {} /dev/null \;
Donc, si le nom se termine par .html ou contient .svn n'importe où dans le chemin, il ne correspondra pas et l'exécution ne sera donc pas exécutée.
J'ai le même problème depuis longtemps et plusieurs solutions peuvent être appliquées dans différentes situations:
ack-grep
est une sorte de "développeur grep
name__" qui par défaut ignore les répertoires de contrôle de version et les fichiers temporaires. La page man
explique comment effectuer une recherche dans des types de fichiers spécifiques et comment définir votre propre .grep
name Les options propres --exclude
et --exclude-dir
de __ peuvent être utilisées très facilement pour ignorer les répertoires file globs et single _ (malheureusement, aucune annotation globale pour les répertoires).find . \( -type d -name '.svn' -o -type f -name '*.html' \) -Prune -o -print0 | xargs -0 grep ...
devrait fonctionner, mais les options ci-dessus sont probablement moins compliquées à long terme.La commande find
suivante effectue le nettoyage des répertoires dont les noms contiennent .svn
. Bien qu’il ne descende pas dans le répertoire, le nom du chemin élagué est imprimé ... (-name '*.svn'
en est la cause!) ..
Vous pouvez filtrer les noms de répertoire via: grep -d skip
qui ignore silencieusement ces "noms de répertoire" en entrée.
Avec GNU grep, vous pouvez utiliser -H
au lieu de /dev/null
. Un problème mineur: \+
peut être beaucoup plus rapide que \;
, par exemple. pour 1 million de fichiers d'une ligne, en utilisant \;
il a fallu 4m20s , en utilisant \+
il n'a fallu que 1.2s .
La méthode suivante utilise xargs
au lieu de -exec
et suppose qu'il n'y a pas de saut de ligne \n
dans aucun de vos fichiers-noms . Telle qu'elle est utilisée ici, xargs
est pratiquement identique à \+
de find.
xargs
peut transmettre des noms de fichiers contenant des espaces consécutifs en modifiant le délimiteur d'entrée en '\n'
avec l'option -d
.
Ceci exclut les répertoires dont les noms contiennent .svn
et ne traite que les fichiers ne se terminant pas par .html
.
find . \( -name '*.svn*' -Prune -o ! -name '*.html' \) |
xargs -d '\n' grep -Hd skip 'SearchString'