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?


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

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.


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

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

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.


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'

2
pour trouver, vous devez ajouter -print0find -print0 | xargs -0 grep 'text'
aliva

1

Utilisation -Idans grep.

Exemple: grep SEARCH_ME -Irs ~/logs.


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"
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.