GNU/Linux >> Tutoriels Linux >  >> Linux

Limiter la sortie de recherche et éviter le signal 13 ?

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 ?
Linux
  1. Sortie vers Stdout et en même temps Grep dans un fichier ?

  2. Trouver un modèle et déplacer ?

  3. Utiliser la commande Grep et localiser ?

  4. Iptables et proxys transparents ?

  5. Utiliser grep et sed pour rechercher et remplacer une chaîne

Comment trouver une chaîne ou un mot spécifique dans les fichiers et les répertoires

Utilisez grep pour rechercher du contenu dans des fichiers et les déplacer s'ils correspondent

Rechercher et copier des fichiers

Recherche de fichiers exécutables à l'aide de ls et grep

Rechercher et renommer un répertoire

Ubuntu grep, find etc:Autorisation refusée et aucune sortie de fichier ou de répertoire de ce type