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 situé dans ou sous un répertoire contenant ".svn", ni aucun fichier se termine par ".html"
La page MAN pour trouver un peu me confond cependant. J'ai essayé d'utiliser -une, 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
find
n'est pas une commandegrep -rl 'SearchString'
find
à rechercher dans un fichier.-name '*.*'
ne trouve pas tous les fichiers: uniquement ceux qui ont un.
nom (l’utilisation de*.*
est typiquement un DOS-isme, alors qu’en Unix, vous n’utilisez normalement que*
pour cela). Pour vraiment faire correspondre tous, il suffit de retirer l'argument tout à fait:find . -exec ...
. Ou si vous souhaitez uniquement appliquer grep aux fichiers (et ignorer les répertoires), faites-lefind . -type f -exec ...
.Réponses:
Vous pouvez utiliser la fonction negate (!) De find pour ne pas faire correspondre les fichiers portant des noms spécifiques:
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.
la source
*.*
correspondance était-elle de s'assurer que seuls les fichiers correspondants contenant un.
? Find correspondra à tous les fichiers en l'absence dename
directive, de sorte que ce qui précède correspondra à tout sauf html et svn-wholename '*.svn*'
plutôt que-name
..svn
répertoires sont exclus des résultats de la recherche.! -name '.'
doit exclure.
des résultats de la recherche.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éveloppeurgrep
" qui ignore par défaut les répertoires de contrôle de version et les fichiers temporaires. Laman
page explique comment rechercher uniquement des types de fichiers spécifiques et comment définir les vôtres .grep
Les propres options--exclude
et--exclude-dir
options peuvent être utilisées très facilement pour ignorer les fichiers globaux et les répertoires simples (pas de globbing pour les répertoires, malheureusement).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 source
La
find
commande suivante élimine les répertoires dont le nom contient.svn
. Bien qu’elle ne descende pas dans le répertoire, le nom du chemin élagué est imprimé ... (-name '*.svn'
c’est la cause!) ..Vous pouvez filtrer les noms de répertoire via:
grep -d skip
qui ignore en silence ces entrées "noms de répertoire".Avec GNU grep, vous pouvez utiliser à la
-H
place de/dev/null
. Comme un problème secondaire:\+
peut être beaucoup plus rapide que\;
, par exemple. pour 1 million de fichiers d'une ligne, son utilisation\;
a pris 4m20s , son utilisation\+
n'a pris que 1.2s .La méthode suivante utilise à la
xargs
place de-exec
, et suppose qu'il n'y a pas de saut\n
de ligne dans aucun de vos noms de fichier . Tel qu'utilisé ici,xargs
c'est à peu près la même chose que find\+
.xargs
peut transmettre des noms de fichiers contenant des espaces consécutifs en modifiant le délimiteur d’entrée'\n'
avec l’-d
option.Ceci exclut les répertoires dont les noms contiennent
.svn
et mettent en attente uniquement les fichiers ne se terminant pas par.html
.la source
\+
variante de l'action -exec. Hourra pour les petits problèmes secondaires!+
le shell n’est pas un caractère spécial, vous n’avez pas besoin de taper\
avant.