Comment puis-je faire en sorte que grep n'imprime pas les erreurs «Aucun fichier ou répertoire»?

217

Je suis en train de parcourir une grande pile de code gérée par git, et chaque fois que je fais une grep, je vois des tas et des tas de messages de la forme:

> grep pattern * -R -n
whatever/.git/svn: No such file or directory

Existe-t-il un moyen de faire disparaître ces lignes?

Alex
la source
1
Ces jours-ci, je recommanderais d'utiliser ag, ackou à la cgrepplace - ils sont beaucoup plus rapides / meilleurs que greppour rechercher des référentiels de code.
lunixbochs
Si vous parcourez le code et cherchez à éviter des répertoires particuliers, vous devriez peut-être regarder ack. C'est un grep conscient du code source, et en tant que tel, il ignorera activement ces répertoires VCS (ainsi que les sauvegardes vi et emacs, les fichiers non sources, etc.).
Brian Agnew,
2
Comment un utilisateur peut-il obtenir des No such file or directorymessages pour des fichiers et / ou des répertoires existants? Ou, inversement, comment grep *obtenir des noms de fichiers qui n'existent pas? S'agit-il d'une condition de concurrence critique, où un autre processus manipule l'arborescence de répertoires (création, renommage et suppression de fichiers) pendant l' grepexécution de?
Scott

Réponses:

300

Vous pouvez utiliser l' indicateur -sou --no-messagespour supprimer les erreurs.

-s, --no-messages supprime les messages d'erreur

grep pattern * -s -R -n
Dogbert
la source
14
@Alex @Dogbert Cela répond à la question, mais '-s' peut masquer les problèmes, par exemple lorsque vous utilisez xargs avec grep. Essayez de créer 2 fichiers dans un répertoire, «aaa.txt» et «a b.txt», contenant tous deux la chaîne «du texte». La commande /bin/ls -1 | xargs grep 'some text'vous donnera "aucun fichier ou répertoire" car elle décompose 'a b.txt' en 2 arguments. Si vous supprimez, vous ne remarquerez pas que vous avez manqué un fichier.
Kelvin
@Kelvin le fait, par exemple si j'utilise findet utilise print0avec xargs -0Est-ce que cela résout le problème? Merci
Luka
1
@Luka Cela devrait résoudre le problème. Vous ne rencontrerez pas de problèmes si vous utilisez toujours ces options NUL, mais si vous ne le faites pas, il est presque garanti (à mon humble avis) que vous oublierez au moment le plus inopportun.
Kelvin
cela fonctionne sur Mac OS X où les autres options (--quiet) ne le font pas
philshem
59

Si vous parcourez un référentiel git, je vous recommande d'utiliser git grep. Vous n'avez pas besoin de passer -Rni le chemin.

git grep pattern

Cela affichera toutes les correspondances de votre répertoire actuel.

Steve Prentice
la source
5
+1 pour la commande utile spécifique à git. Ne fonctionnera pas pour svn cependant :-)
cadrian
2
+1 C'est la commande git qui me manque - cela me permet de rechercher une chaîne de l'état de l'arborescence dans n'importe quel commit (en ajoutant le commit après "pattern").
Kelvin
1
Avec le plugin fugitif, Ggreprecherche également à partir du haut du répertoire Git au lieu du répertoire actuel.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
Cela semble être beaucoup plus rapide que grep standard. (Peut-être qu'il ignore les fichiers binaires, etc.? Aucune idée, mais utile.)
Daniel
10

De telles erreurs sont généralement envoyées au flux "erreur standard", que vous pouvez diriger vers un fichier ou simplement faire disparaître sur la plupart des commandes:

grep pattern * -R -n 2>/dev/null
lunixbochs
la source
Répond à la question, mais peut masquer les problèmes. Voir mon commentaire sous la réponse de Dogbert.
Kelvin
5

J'ai vu cela se produire plusieurs fois, avec des liens brisés (liens symboliques pointant vers des fichiers qui n'existent pas), grep essaie de rechercher sur le fichier cible, qui n'existe pas (d'où le message d'erreur correct et précis).

Normalement, je ne me dérange pas en effectuant des tâches sysadmin sur la console, mais à partir de scripts, je cherche des fichiers texte avec "find", puis grep chacun:

find /etc -type f -exec grep -nHi -e "widehat" {} \;

Au lieu de:

grep -nRHi -e "widehat" /etc
Isaac Uribe
la source
4

Je ne laisse généralement pas grep faire la récursivité elle-même. Il y a généralement quelques répertoires que vous souhaitez ignorer (.git, .svn ...)

Vous pouvez faire des alias intelligents avec des positions comme celle-ci:

find . \( -name .svn -o -name .git \) -prune -o -type f -exec grep -Hn pattern {} \;

Cela peut sembler exagéré à première vue, mais lorsque vous devez filtrer certains modèles, c'est assez pratique.

cadrian
la source
1
+1. C'est bien mieux que de supprimer les erreurs. Cependant, je pense que vous avez oublié l' -execavant avant votre grep.
Kelvin
1
Qu'est-ce que ça veut dire? \( -name .svn -o -name .git \)
sbhatla
Pourquoi ne pas utiliser les drapeaux --exclude ou --exlcude-dir de grep?
Choylton B. Higginbottom
1
@sbhatla les parenthèses créent un ordre d'opérations pour la commande find. stackoverflow.com/questions/24338777/…
Choylton B. Higginbottom
4

Avez-vous essayé l' -0option dans xargs ? Quelque chose comme ça:

ls -r1 | xargs -0 grep 'some text'
cokedude
la source
2
pour trouver, vous devez ajouter -print0find -print0 | xargs -0 grep 'text'
aliva
1

Utilisation -Idans grep.

Exemple: grep SEARCH_ME -Irs ~/logs.

Bala
la source
1
-Iignore les fichiers binaires - c'est équivalent à --binary-files=without-match. Cependant, il ne supprime pas les messages "Aucun fichier ou répertoire".
mwfearnley
0

Je redirige stderrvers stdout, puis j'utilise invert-match ( -v) de grep pour exclure la chaîne d'avertissement / d'erreur que je souhaite masquer:

grep -r <pattern> * 2>&1 | grep -v "No such file or directory"
talleyho
la source