Znajdź tylko kilka pierwszych pasujących plików przy użyciu funkcji Znajdź?

17

Powiedzmy, że *.txtw katalogu mogą znajdować się setki plików. Chcę tylko znaleźć pierwsze trzy *.txtpliki, a następnie zakończyć proces wyszukiwania.

Jak to osiągnąć za pomocą findnarzędzia? Szybko przejrzałem jego stronę podręcznika, nie wydawało mi się to taką opcją.

mitnk
źródło
3
Możesz użyć find . -name '*.txt' -print -quittylko pokazać pierwszy mecz i pozwolić findwyjść po pierwszym meczu. Nie wiem, czy możliwe jest dostosowanie do przypadku „wyjście po znalezieniu n dopasowań”.
NN

Odpowiedzi:

22

Możesz przesyłać dane wyjściowe findprzez head:

find . -name '*.txt' | head -n 3
Chris Card
źródło
2
Wiedziałem o tym, chcę zakończyć proces wyszukiwania po znalezieniu pierwszych trzech pasujących plików. Może być ogromna ilość dopasowanych plików, nie dbam o to.
mitnk
2
Myślę, że polecenie find zostaje zakończone, gdy szef wydrukuje pierwsze 3 pliki
Chris Card
1
Tak, to dziwne, ale masz rację.
mitnk
19
To wcale nie jest dziwne - tak działają potoki w systemie UNIX. headuruchamia się i czeka na dane wejściowe z lewej strony potoku. Następnie finduruchamia się i wyszukuje pliki spełniające określone kryteria, wysyłając dane wyjściowe przez potok. Po headotrzymaniu i wydrukowaniu żądanej liczby linii, kończy się, zamykając potok. findzauważa zamkniętą rurę i również się kończy. Prosty, elegancki i wydajny.
D_Bye
3
Podsumowując, -n 3jest zgodny z POSIX , a zatem może być bardziej przenośny.
l0b0
4

Ta druga odpowiedź jest nieco błędna. Poleceniem jest

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

Potem jest wyjaśnienie w jednym z komentarzy [moje podkreślenie]:

headuruchamia się i czeka na dane wejściowe z lewej strony potoku. Następnie finduruchamia się i wyszukuje pliki spełniające określone kryteria, wysyłając dane wyjściowe przez potok. Po headotrzymaniu i wydrukowaniu żądanej liczby linii, kończy się, zamykając potok. findzauważa zamkniętą rurę i również się kończy. Prosty, elegancki i wydajny .

To prawie prawda.

Problem polega na findtym, że zamknięty potok pojawia się tylko wtedy, gdy próbuje do niego napisać - w tym przypadku następuje odnalezienie czwartego dopasowania. Ale jeśli nie będzie czwartego meczu, findbędzie kontynuowany. Twoja skorupa będzie czekać! Jeśli stanie się to w skrypcie, skrypt zaczeka, mimo że wiemy, że wyjście potoku jest ostateczne i nic nie można do niego dodać. Nie tak wydajne.

Efekt jest nieistotny, jeśli ten konkretny findproces kończy się sam z siebie, ale przy złożonym wyszukiwaniu w dużym drzewie plików polecenie może niepotrzebnie opóźniać to, co chcesz zrobić dalej.

Niezupełnie idealnym rozwiązaniem jest uruchomienie

( find … & ) | head -n 3

W ten sposób po headwyjściu powłoka kontynuuje natychmiast. findProces w tle może być wówczas zignorowany (prędzej czy później zakończy się) lub ukierunkowany na pkillcoś.


Aby udowodnić koncepcję, której możesz szukać /. Oczekujemy tylko jednego meczu, ale findszuka go wszędzie i może to zająć dużo czasu.

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

Zakończ go za pomocą Ctrl+, Cgdy tylko zobaczysz problem. Teraz porównaj:

pidof find ; ( find / -wholename / 2>/dev/null & ) | head -n 1 ; pidof find
Kamil Maciorowski
źródło