J'ai un répertoire avec ~ 1 million de fichiers et j'ai besoin de rechercher des modèles particuliers. Je sais comment faire pour tous les fichiers :
find /path/ -exec grep -H -m 1 'pattern' {} ;
La sortie complète n'est pas souhaitée (trop lente). Plusieurs premiers hits sont corrects, j'ai donc essayé de limiter le nombre de lignes :
find /path/ -exec grep -H -m 1 'pattern' {} ; | head -n 5
Cela donne 5 lignes suivies de
find: `grep' terminated by signal 13
et find continue de travailler. C'est bien expliqué ici. J'ai essayé de quit action :
find /path/ -exec grep -H -m 1 'pattern' {} ; -quit
Cela ne génère que la première correspondance.
Est-il possible de limiter la sortie de recherche avec un nombre spécifique de résultats (comme fournir un argument pour quit similaire à head -n ) ?
Réponse acceptée :
Puisque vous utilisez déjà les extensions GNU (-quit , -H , -m1 ), vous pourriez aussi bien utiliser GNU grep 's -r option, avec --line-buffered il affiche donc les correspondances dès qu'elles sont trouvées, il est donc plus probable qu'un SIGPIPE soit tué dès qu'il écrit la 6ème ligne :
grep -rHm1 --line-buffered pattern /path | head -n 5
Avec find , vous devrez probablement faire quelque chose comme :
find /path -type f -exec sh -c '
grep -Hm1 --line-buffered pattern "[email protected]"
[ "$(kill -l "$?")" = PIPE ] && kill -s PIPE "$PPID"
' sh {} + | head -n 5
C'est-à-dire envelopper grep en sh (vous voulez toujours exécuter aussi peu de grep autant d'invocations que possible, d'où le {} + ), et ont sh tuer son parent (find ) quand grep meurt d'un SIGPIPE.
Une autre approche pourrait être d'utiliser xargs comme alternative à -exec {} + . xargs quitte immédiatement lorsqu'une commande qu'il génère meurt d'un signal donc dans :
find . -type f -print0 |
xargs -r0 grep -Hm1 --line-buffered pattern |
head -n 5
(-r et -0 étant des extensions GNU). Dès que grep écrit dans le tube cassé, à la fois grep et xargs va sortir et find se quittera également la prochaine fois qu'il imprimera quelque chose après cela. Exécution de find sous stdbuf -oL pourrait le faire arriver plus tôt.
Une version POSIX pourrait être :
trap - PIPE # restore default SIGPIPE handler in case it was disabled
RE=pattern find /path -type f -exec sh -c '
for file do
awk '''
$0 ~ ENVIRON["RE"] {
print FILENAME ": " $0
exit
}''' < "$file"
if [ "$(kill -l "$?")" = PIPE ]; then
kill -s PIPE "$PPID"
exit
fi
done' sh {} + | head -n 5
Très inefficace car il exécute plusieurs commandes pour chaque fichier.
En relation:Ubuntu - Comment verrouiller la vitesse du ventilateur pour AMD GPU dans Ubuntu 20.04 ?