Je recherche la chaîne foo=
dans des fichiers texte dans une arborescence de répertoires. C'est sur une machine Linux commune, j'ai un shell bash:
grep -ircl "foo=" *
Les répertoires contiennent également de nombreux fichiers binaires qui correspondent à "foo =". Comme ces résultats ne sont pas pertinents et ralentissent la recherche, je veux que grep ignore la recherche de ces fichiers (principalement des images JPEG et PNG). Comment pourrais-je faire ça?
Je sais qu'il existe des options --exclude=PATTERN
et --include=PATTERN
, mais quel est le format du modèle? La page de manuel de grep dit:
--include=PATTERN Recurse in directories only searching file matching PATTERN.
--exclude=PATTERN Recurse in directories skip file matching PATTERN.
La recherche sur grep include , grep include exclude , grep exclude et les variantes n'ont trouvé rien de pertinent
S'il n'y a une meilleure façon de saluer que dans certains fichiers, je suis tout à fait d'accord; déplacer les fichiers incriminés n'est pas une option. Je ne peux pas rechercher uniquement certains répertoires (la structure des répertoires est un gros gâchis, avec tout partout). De plus, je ne peux rien installer, donc je dois faire avec des outils communs (comme grep ou la découverte suggérée ).
--exclude-dir=.svn
, donc grep n'y va pas du toutgrep -r --exclude-dir=var "pattern" .
Réponses:
Utilisez la syntaxe de globbing shell:
La syntaxe de
--exclude
est identique.Notez que l'étoile est échappée avec une barre oblique inverse pour l'empêcher d'être développée par le shell (la citer, comme, par exemple
--include="*.{cpp,h}"
, fonctionnerait tout aussi bien). Sinon, si vous aviez des fichiers dans le répertoire de travail actuel qui correspondaient au modèle, la ligne de commande se développerait en quelque chose commegrep pattern -r --include=foo.cpp --include=bar.h rootdir
, qui ne rechercherait que les fichiers nommésfoo.cpp
etbar.h
, ce qui n'est probablement pas ce que vous vouliez.la source
grep pattern -r --include="*.{cpp,h}" rootdir
grep pattern -r --include=foo.cpp --include=bar.h rootdir
, qui ne recherchera que les fichiers nomméfoo.cpp
oubar.h
. Si vous n'avez aucun fichier correspondant au glob dans le répertoire courant, le shell transmet le glob à grep, qui l'interprète correctement.--exclude-dir
option. Les mêmes règles s'appliquent cependant. Seul le nom de fichier du répertoire correspond, pas un chemin.--include
ne semble pas fonctionner après--exclude
. Je suppose que cela n'a même pas de sens d'essayer, sauf que j'ai unalias
à grep avec une longue liste de--exclude
et--exclude-dir
, que j'utilise pour rechercher du code, ignorer les bibliothèques et échanger des fichiers et des choses. J'aurais espéré quegrep -r --exclude='*.foo' --include='*.bar'
cela fonctionnerait, donc je pourrais me limiteralias
à--include='*.bar'
seulement, mais il semble ignorer le--include
et inclure tout ce qui n'est pas un fichier .foo. Permuter l'ordre des--include
et--exclude
fonctionne, mais hélas, ce n'est pas utile avec monalias
.PATTERN
. Une demi-heure, je ne trouve aucune description de ce qu'ils attendent là-basSi vous souhaitez simplement ignorer les fichiers binaires, je vous suggère de regarder l'
-I
option (majuscule i). Il ignore les fichiers binaires. J'utilise régulièrement la commande suivante:Il recherche récursivement, ignore les fichiers binaires et ne regarde pas à l'intérieur des dossiers cachés de Subversion, quel que soit le motif que je veux. Je l'ai aliasé "grepsvn" sur ma boîte au travail.
la source
--exclude-dir
n'est pas disponible partout. ma boîte RH au travail avec GNU grep 2.5.1 ne l'a pas.--exclude-dir
n'est pas disponible? Dans toutes mes tentatives,--exclude
ne semble pas correspondre à la facture.--exclude-dir="\.git"
. :-)Veuillez jeter un œil à ack , qui est conçu exactement pour ces situations. Votre exemple de
se fait avec ack comme
car ack ne regarde jamais dans les fichiers binaires par défaut, et -r est activé par défaut. Et si vous ne voulez que des fichiers CPP et H, faites simplement
la source
apt-get
dans Ubuntu :)awk
grep 2.5.3 a introduit le paramètre --exclude-dir qui fonctionnera comme vous le souhaitez.
Vous pouvez également définir une variable d'environnement: GREP_OPTIONS = "- exclude-dir = .svn"
Je vais cependant seconder le vote d' Andy pour l' ack , c'est le meilleur.
la source
J'ai trouvé cela après longtemps, vous pouvez ajouter plusieurs inclusions et exclusions comme:
la source
La commande suggérée:
est conceptuellement faux, car --exclude fonctionne sur le nom de base. Autrement dit, il ne sautera que le .svn dans le répertoire courant.
la source
Dans grep 2.5.1, vous devez ajouter cette ligne au profil ~ / .bashrc ou ~ / .bash
la source
Je trouve que la sortie de grep grep est très utile parfois:
Cependant, cela ne l'empêche pas de rechercher les fichiers binaires.
la source
grep -I
pour ignorer les fichiers binaires.Si vous n'êtes pas opposé à l'utilisation
find
, j'aime sa-prune
fonctionnalité:Sur la première ligne, vous spécifiez le répertoire que vous souhaitez rechercher.
.
(répertoire courant) est un chemin valide, par exemple.Sur les 2e et 3e lignes, l' utilisation
"*.png"
,"*.gif"
,"*.jpg"
et ainsi de suite. Utilisez autant de ces-o -name "..." -prune
constructions que vous avez de motifs.Sur la 4ème ligne, vous en avez besoin d'un autre
-o
(il spécifie "ou" àfind
), les motifs que vous voulez, et vous avez besoin d'un-print
ou-print0
à la fin. Si vous voulez juste « tout le reste » qui reste après la taille du*.gif
,*.png
, etc. images, puis utilisez-o -print0
et vous avez terminé avec la ligne 4.Enfin, sur la 5ème ligne se trouve le canal vers
xargs
lequel prend chacun de ces fichiers résultants et les stocke dans une variableFILENAME
. Il passe ensuitegrep
les-IR
drapeaux, le"pattern"
, puisFILENAME
est développé parxargs
pour devenir la liste des noms de fichiers trouvés parfind
.Pour votre question particulière, la déclaration peut ressembler à quelque chose comme:
la source
-false
immédiatement après chaque-prune
afin d'oublier d'utiliser-print0
ou une sorte deexec
commande n'imprimera pas réellement les fichiers que vous vouliez exclure:-name "*.png" -prune -false -o name "*.gif -prune -false
...Sur CentOS 6.6 / Grep 2.6.3, je dois l'utiliser comme ceci:
Notez l'absence de signe égal « = » (sinon
--include
,--exclude
,include-dir
et--exclude-dir
sont ignorées)la source
git grep
Utilisation
git grep
optimisée pour les performances et visant à rechercher dans certains fichiers.Par défaut, il ignore les fichiers binaires et respecte votre
.gitignore
. Si vous ne travaillez pas avec la structure Git, vous pouvez toujours l'utiliser en passant--no-index
.Exemple de syntaxe:
Pour plus d'exemples, voir:
la source
Je suis dilettante, d'accord, mais voici à quoi ressemble mon ~ / .bash_profile:
Notez que pour exclure deux répertoires, j'ai dû utiliser --exclude-dir deux fois.
la source
Essaye celui-là:
Fondé ici: http://www.unix.com/shell-programming-scripting/42573-search-files-excluding-binary-files.html
la source
Si vous effectuez une recherche non récursive, vous pouvez utiliser des modèles Glop pour faire correspondre les noms de fichiers.
comprend html et txt. Il recherche uniquement dans le répertoire courant.
Pour rechercher dans les sous-répertoires:
Dans les sous-répertoires:
la source
ripgrep
Il s'agit de l'un des outils les plus rapides conçus pour rechercher récursivement votre répertoire actuel. Il est écrit en Rust , construit sur le moteur regex de Rust pour une efficacité maximale. Consultez l' analyse détaillée ici .
Vous pouvez donc simplement exécuter:
Il respecte votre
.gitignore
et ignore automatiquement les fichiers / répertoires cachés et les fichiers binaires.Vous pouvez toujours personnaliser l'inclusion ou l'exclusion de fichiers et de répertoires à l'aide de
-g
/--glob
. Les règles globales correspondent aux.gitignore
globes. Cherchezman rg
de l'aide.Pour plus d'exemples, voir: Comment exclure certains fichiers ne correspondant pas à certaines extensions avec grep?
Sur macOS, vous pouvez installer via
brew install ripgrep
.la source
find et xargs sont vos amis. Utilisez-les pour filtrer la liste des fichiers plutôt que celle de grep --exclude
Essayez quelque chose comme
L'avantage de s'y habituer est qu'il est extensible à d'autres cas d'utilisation, par exemple pour compter les lignes dans tous les fichiers non png:
Pour supprimer tous les fichiers non png:
etc.
Comme indiqué dans les commentaires, si certains fichiers peuvent avoir des espaces dans leurs noms, utilisez
-print0
et à laxargs -0
place.la source
ces scripts n'accomplissent pas tout le problème ... Essayez mieux:
ce script est tellement meilleur, car il utilise des expressions régulières "réelles" pour éviter les répertoires de la recherche. séparez simplement les noms de dossier ou de fichier par "\ |" sur le grep -v
Profitez-en! trouvé sur mon shell linux! XD
la source
Regardez @ celui-ci.
la source
L'
--binary-files=without-match
option GNUgrep
permet de sauter les fichiers binaires. (Équivalent au-I
commutateur mentionné ailleurs.)(Cela peut nécessiter une version récente de
grep
; 2.5.3 l'a au moins.)la source
adapté au fichier tcsh .alias:
Il m'a fallu un certain temps pour comprendre que la partie {mm, m, h, cc, c} ne devait PAS être entre guillemets. ~ Keith
la source
Pour ignorer tous les résultats binaires de grep
La partie awk filtrera toutes les lignes de correspondance du fichier binaire foo
la source
Essaye ça:
--F
" sous currdir .. (ou liez un autre dossier renommé à "--F
" iedouble-minus-F
.#> grep -i --exclude-dir="\-\-F" "pattern" *
la source