Только найти первые несколько подходящих файлов, используя поиск?

17

Скажем, *.txtв каталоге могут быть сотни файлов. Я только хочу найти первые три *.txtфайла и затем выйти из процесса поиска.

Как этого добиться с помощью findутилиты? Я пробежался по его man-странице, казалось, не такой вариант для этого.

mitnk
источник
3
Вы можете использовать find . -name '*.txt' -print -quitтолько показать первый матч и разрешить findвыход после первого матча. Я не знаю, можно ли приспособиться к случаю «выход после нахождения n совпадений».
NN

Ответы:

22

Вы можете передать вывод findчерез head:

find . -name '*.txt' | head -n 3
Крис Кард
источник
2
Я знал это, я хочу выйти из процесса поиска после обнаружения первых трех совпавших файлов. Там может быть огромное количество совпавших файлов, мне все равно.
Mitnk
2
Я думаю, что команда find завершается после того, как head напечатает первые 3 файла
Chris Card
1
Да, это странно, но вы правы.
Mitnk
19
Это совсем не странно - так работают каналы в UNIX. headзапускается и ожидает ввода с левой стороны трубы. Затем findзапускается и ищет файлы, соответствующие указанным критериям, отправляя свои выходные данные по каналу. Когда headполучено и напечатано количество запрошенных строк, оно завершается, закрывая канал. findзамечает закрытую трубу, и она также заканчивается. Просто, элегантно и эффективно.
D_Bye
3
Подводя итог, -n 3можно сказать, что он совместим с POSIX и поэтому может быть более переносимым.
мая 1913 года
4

Этот другой ответ несколько ошибочен. Команда

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

Тогда есть объяснение в одном из комментариев [выделено мной]:

headзапускается и ожидает ввода с левой стороны трубы. Затем findзапускается и ищет файлы, соответствующие указанным критериям, отправляя свои выходные данные по каналу. Когда headполучено и напечатано количество запрошенных строк, оно завершается, закрывая канал. findзамечает закрытую трубу, и она также заканчивается. Просто, элегантно и эффективно .

Это почти правда.

Проблема в том, findчто закрытая труба замечается только тогда, когда она пытается записать в нее - в этом случае, когда найдено 4-е совпадение. Но если 4-го матча нет, то findпродолжим. Ваша оболочка будет ждать! Если это происходит в сценарии, сценарий будет ждать, несмотря на то, что мы уже знаем, что вывод канала является окончательным, и к нему ничего нельзя добавить. Не так эффективно.

Эффект незначителен, если этот конкретный findпроцесс завершается быстро сам по себе, но при сложном поиске в большом дереве файлов команда может излишне отложить все, что вы хотите сделать дальше.

Не очень идеальное решение - запустить

( find … & ) | head -n 3

Таким образом, при headвыходе оболочка продолжается немедленно. Фоновый findпроцесс может тогда быть проигнорирован (он рано или поздно завершится) или будет нацелен на pkillчто-либо.


Чтобы доказать концепцию, вы можете искать /. Мы ожидаем только один матч, но ищем findего везде, и это может занять много времени.

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

Завершите его с помощью Ctrl+, Cкак только увидите проблему. Теперь сравните:

pidof find ; ( find / -wholename / 2>/dev/null & ) | head -n 1 ; pidof find
Камиль Мачоровски
источник