Ne rechercher que les premiers fichiers correspondants à l'aide de find?

17

Supposons qu'il puisse y avoir des centaines de *.txtfichiers dans un répertoire. Je veux seulement trouver les trois premiers *.txtfichiers, puis quitter le processus de recherche.

Comment y parvenir en utilisant l' findutilitaire? J'ai eu un rapide survol sur sa page de manuel, ne semblait pas une telle option pour cela.

mitnk
la source
3
Vous pouvez utiliser find . -name '*.txt' -print -quituniquement afficher la première correspondance et laisser findsortir après la première correspondance. Je ne sais pas s'il est possible de s'adapter au cas "sortie après avoir trouvé n correspondances".
NN

Réponses:

22

Vous pouvez diriger la sortie de findvia head:

find . -name '*.txt' | head -n 3
Chris Card
la source
2
Je le savais, je veux quitter le processus de recherche après avoir découvert les trois premiers fichiers correspondants. Il peut y avoir une énorme quantité de fichiers correspondants, je m'en fous.
mitnk
2
Je pense que la commande find est terminée une fois que la tête a imprimé les 3 premiers fichiers
Chris Card
1
Oui, c'est étrange, mais vous avez raison.
mitnk
19
Ce n'est pas du tout étrange - c'est comme ça que les pipes fonctionnent sous UNIX. headdémarre et attend l'entrée du côté gauche du tuyau. Ensuite finddémarre et recherche les fichiers qui correspondent aux critères spécifiés, envoyer sa sortie par le tuyau. Quand heada reçu et imprimé le nombre de lignes demandées, il se termine, fermant le tuyau. findremarque le tuyau fermé et il se termine également. Simple, élégant et efficace.
D_Bye
3
Pour résumer, -n 3est compatible POSIX , et donc susceptible d'être plus portable.
l0b0
4

Cette autre réponse est quelque peu imparfaite. La commande est

find . -name '*.txt' | head -n 3

Ensuite, il y a une explication dans l'un des commentaires [c'est moi qui souligne]:

headdémarre et attend l'entrée du côté gauche du tuyau. Ensuite finddémarre et recherche les fichiers qui correspondent aux critères spécifiés, envoyer sa sortie par le tuyau. Quand heada reçu et imprimé le nombre de lignes demandées, il se termine, fermant le tuyau. findremarque le tuyau fermé et il se termine également. Simple, élégant et efficace .

C'est presque vrai.

Le problème est que findle tube fermé n'est remarqué que lorsqu'il essaie d'y écrire - dans ce cas, c'est lorsque la 4e correspondance est trouvée. Mais s'il n'y a pas de 4e match, findcela continuera. Votre coquille attendra! Si cela se produit dans un script, le script attendra, malgré le fait que nous savons déjà que la sortie du tube est finale et que rien ne peut y être ajouté. Pas si efficace.

L'effet est négligeable si ce particulier se findtermine rapidement par lui-même mais avec une recherche complexe dans une grande arborescence de fichiers, la commande peut retarder inutilement tout ce que vous voulez faire ensuite.

La solution pas si parfaite est d'exécuter

( find … & ) | head -n 3

De cette façon, à la headsortie, le shell continue immédiatement. Le findprocessus d' arrière-plan peut alors être ignoré (il se terminera tôt ou tard) ou ciblé avec pkillou quelque chose.


Pour prouver le concept que vous pouvez rechercher /. Nous n'attendons qu'un seul match, mais nous le cherchons findpartout et cela peut prendre beaucoup de temps.

find / -wholename / 2>/dev/null | head -n 1

Arrêtez-le avec Ctrl+ Cdès que vous voyez le problème. Comparez maintenant:

pidof find ; ( find / -wholename / 2>/dev/null & ) | head -n 1 ; pidof find
Kamil Maciorowski
la source