Odpowiedzi:
Możesz przesyłać dane wyjściowe find
przez head
:
find . -name '*.txt' | head -n 3
head
uruchamia się i czeka na dane wejściowe z lewej strony potoku. Następnie find
uruchamia się i wyszukuje pliki spełniające określone kryteria, wysyłając dane wyjściowe przez potok. Po head
otrzymaniu i wydrukowaniu żądanej liczby linii, kończy się, zamykając potok. find
zauważa zamkniętą rurę i również się kończy. Prosty, elegancki i wydajny.
-n 3
jest zgodny z POSIX , a zatem może być bardziej przenośny.
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]:
head
uruchamia się i czeka na dane wejściowe z lewej strony potoku. Następniefind
uruchamia się i wyszukuje pliki spełniające określone kryteria, wysyłając dane wyjściowe przez potok. Pohead
otrzymaniu i wydrukowaniu żądanej liczby linii, kończy się, zamykając potok.find
zauważa zamkniętą rurę i również się kończy. Prosty, elegancki i wydajny .
To prawie prawda.
Problem polega na find
tym, ż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, find
bę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 find
proces 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 head
wyjściu powłoka kontynuuje natychmiast. find
Proces w tle może być wówczas zignorowany (prędzej czy później zakończy się) lub ukierunkowany na pkill
coś.
Aby udowodnić koncepcję, której możesz szukać /
. Oczekujemy tylko jednego meczu, ale find
szuka 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
find . -name '*.txt' -print -quit
tylko pokazać pierwszy mecz i pozwolićfind
wyjść po pierwszym meczu. Nie wiem, czy możliwe jest dostosowanie do przypadku „wyjście po znalezieniu n dopasowań”.