Je cherche la chaîne foo=
dans les fichiers texte d'une arborescence de répertoires. C'est sur une machine Linux commune, j'ai bash Shell:
grep -ircl "foo=" *
Dans les répertoires se trouvent également de nombreux fichiers binaires qui correspondent à "foo =". Comme ces résultats ne sont pas pertinents et ralentissent la recherche, je souhaite que grep ignore la recherche dans ces fichiers (principalement des images JPEG et PNG). Comment je ferais ça?
Je sais qu'il existe les options --exclude=PATTERN
et --include=PATTERN
, mais quel est le format du motif? 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.
Recherche sur grep include, grep include exclure, grep exclude et les variantes n'ont rien trouvé de pertinent
S'il y a un meilleur moyen de grepping que dans certains fichiers, je suis pour. 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 désordre immense, avec tout partout). De plus, je ne peux rien installer, je dois donc utiliser des outils courants (comme grep ou suggéré trouver).
Utilisez la syntaxe de globbing du shell:
grep pattern -r --include=\*.{cpp,h} rootdir
La syntaxe pour --exclude
est identique.
Notez que l'étoile est échappée avec une barre oblique inverse pour l'empêcher d'être étendue par le Shell (le citer, comme --include="*.{cpp,h}"
, fonctionnerait aussi bien). Sinon, si le répertoire de travail en cours contient des fichiers correspondant au modèle, la ligne de commande se développera comme suit: grep pattern -r --include=foo.cpp --include=bar.h rootdir
, qui ne recherchera que les fichiers nommés foo.cpp
et bar.h
, qui est très probablement pas ce que vous vouliez.
Si vous voulez juste ignorer les fichiers binaires, je vous suggère de regarder l'option -I
(majuscule i). Il ignore les fichiers binaires. J'utilise régulièrement la commande suivante:
grep -rI --exclude-dir="\.svn" "pattern" *
Il effectue une recherche récursive, ignore les fichiers binaires et ne cherche pas dans les dossiers cachés de Subversion, quel que soit le motif que je souhaite. Je l'ai aliasé comme "grepsvn" sur ma boîte au travail.
S'il vous plaît jeter un oeil à ack , qui est conçu pour exactement ces situations. Votre exemple de
grep -ircl --exclude=*.{png,jpg} "foo=" *
est fait avec ack comme
ack -icl "foo="
car ack ne recherche jamais dans les fichiers binaires par défaut et -r est activé par défaut. Et si vous voulez seulement les fichiers CPP et H, alors faites juste
ack -icl --cpp "foo="
J'ai trouvé cela après un long moment, vous pouvez ajouter plusieurs inclus et exclure comme:
grep "z-index" . --include=*.js --exclude=*js/lib/* --exclude=*.min.js
La commande suggérée:
grep -Ir --exclude="*\.svn*" "pattern" *
est conceptuellement faux, car --exclude fonctionne sur le nom de base. En d'autres termes, il ignorera uniquement le fichier .svn du répertoire en cours.
Dans grep 2.5.1, vous devez ajouter cette ligne à ~/.bashrc ou ~/.bash_profile
export GREP_OPTIONS="--exclude=\*.svn\*"
Je trouve la sortie de grepping grep très utile parfois:
grep -rn "foo=" . | grep -v "Binary file"
Bien que cela ne l'empêche pas réellement de rechercher les fichiers binaires.
Sur CentOS 6.6/Grep 2.6.3, je dois l’utiliser comme ceci:
grep "term" -Hnir --include \*.php --exclude-dir "*excluded_dir*"
Notez l'absence de signe égal "=" (sinon --include
, --exclude
, include-dir
et --exclude-dir
sont ignorés)
Si vous n'êtes pas opposé à l'utilisation de find
, j'aime bien sa fonction -Prune
:
find [directory] \
-name "pattern_to_exclude" -Prune \
-o -name "another_pattern_to_exclude" -Prune \
-o -name "pattern_to_INCLUDE" -print0 \
| xargs -0 -I FILENAME grep -IR "pattern" FILENAME
Sur la première ligne, vous spécifiez le répertoire que vous souhaitez rechercher. .
(répertoire actuel) est un chemin valide, par exemple.
Sur les 2ème et 3ème lignes, utilisez "*.png"
, "*.gif"
, "*.jpg"
, etc. Utilisez autant de ces constructions -o -name "..." -Prune
que vous avez de modèles.
Sur la 4ème ligne, vous 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 simplement "tout le reste" qui reste après la taille des images *.gif
, *.png
, etc., utilisez -o -print0
et vous en avez terminé avec la 4ème ligne.
Enfin, sur la cinquième ligne, se trouve le tuyau vers xargs
qui prend chacun des fichiers résultants et les stocke dans une variable FILENAME
. Il passe ensuite grep
aux drapeaux -IR
, au "pattern"
, puis à FILENAME
est développé par xargs
pour devenir cette liste de noms de fichiers trouvés par find
.
Pour votre question particulière, l'énoncé peut ressembler à quelque chose comme:
find . \
-name "*.png" -Prune \
-o -name "*.gif" -Prune \
-o -name "*.svn" -Prune \
-o -print0 | xargs -0 -I FILES grep -IR "foo=" FILES
Je suis un dilettante, d'accord, mais voici à quoi ressemble mon ~/.bash_profile:
export GREP_OPTIONS = "- orl --exclude-dir = .svn --exclude-dir = .cache --color = auto" GREP_COLOR = '1; 32'
Notez que pour exclure deux répertoires, j'ai dû utiliser --exclude-dir deux fois.
git grep
Utilisez _git grep
_ qui est optimisé pour la performance et vise à 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:
_git grep --no-index "some_pattern"
_
Pour plus d'exemples, voir:
Essaye celui-là:
$ find. -name "* .txt" -type f -print | fichier xargs | grep "foo =" | cut -d: -f1
Fondée ici: http://www.unix.com/Shell-programming-scripting/42573-search-files-excluding-binary-files.html
Si vous effectuez une recherche non récursive, vous pouvez utiliser modèles glop pour faire correspondre les noms de fichiers.
grep "foo" *.{html,txt}
comprend html et txt. Il recherche uniquement dans le répertoire actuel.
Pour rechercher dans les sous-répertoires:
grep "foo" */*.{html,txt}
Dans les sous-répertoires:
grep "foo" */*/*.{html,txt}
Regardez @ celui-ci.
grep --exclude="*\.svn*" -rn "foo=" * | grep -v Binary | grep -v tags
ces scripts n'accomplissent pas tout le problème ... Essayez mieux:
du -ha | grep -i -o "\./.*" | grep -v "\.svn\|another_file\|another_folder" | xargs grep -i -n "$1"
ce script est tellement meilleur, car il utilise de "vraies" expressions régulières pour éviter les répertoires de la recherche. il suffit de séparer les noms de dossier ou de fichier avec "\ |" sur le grep -v
profitez-en! trouvé sur mon shell linux! XD
Dans les répertoires sont également nombreux fichiers binaires. Je ne peux pas rechercher uniquement certains répertoires (la structure des répertoires est un gros désordre). Y a-t-il une meilleure façon de grepping que dans certains fichiers?
ripgrep
C'est l'un des outils les plus rapides conçus pour rechercher de manière récursive votre répertoire actuel. Il est écrit Rust , construit sur le moteur de regex de Rust pour une efficacité maximale. Vérifiez le analyse détaillée ici .
Donc, vous pouvez juste courir:
rg "some_pattern"
Il respecte votre .gitignore
et ignore automatiquement les fichiers/répertoires cachés et les fichiers binaires.
Vous pouvez toujours personnaliser les fichiers et les répertoires d'inclusion ou d'exclusion à l'aide de -g
/--glob
. Les règles de globalisation correspondent à .gitignore
globs. Vérifiez man rg
pour obtenir de l'aide.
Pour plus d'exemples, voir: Comment exclure des fichiers ne correspondant pas à certaines extensions avec grep?
Sur macOS, vous pouvez installer via brew install ripgrep
.
find et xargs sont vos amis. Utilisez-les pour filtrer la liste de fichiers plutôt que celle de grep --exclude
Essayez quelque chose comme
find . -not -name '*.png' -o -type f -print | xargs grep -icl "foo="
approprié pour tcsh fichier .alias:
alias gisrc 'grep -I -r -i --exclude="*\.svn*" --include="*\."{mm,m,h,cc,c} \!* *'
Il m'a fallu un certain temps pour comprendre que la partie {mm, m, h, cc, c} ne devrait PAS être entre guillemets. ~ Keith
L'option --binary-files=without-match
de GNU grep
lui permet d'ignorer les fichiers binaires. (Équivalent au commutateur -I
mentionné ailleurs.)
(Cela pourrait nécessiter une version récente de grep
; 2.5.3 l'a au moins.)
Pour ignorer tous les résultats binaires de grep
grep -Ri "pattern" * | awk '{if($1 != "Binary") print $0}'
La partie awk filtrera toutes les lignes du fichier binaire