
Может быть, это немного странно, и, возможно, есть другие инструменты, позволяющие это сделать, но, ну...
Я использую следующую классическую команду bash для поиска всех файлов, содержащих какую-либо строку:
find . -type f | xargs grep "something"
У меня много файлов на разных глубинах. Мне достаточно первого появления "чего-то", но find продолжает поиск и долго завершает оставшиеся файлы. Я бы хотел сделать что-то вроде "обратной связи" от grep к find, чтобы find мог прекратить поиск других файлов. Возможно ли это?
решение1
Просто оставьте это в пределах поиска:
find . -type f -exec grep "something" {} \; -quit
Вот как это работает:
Будет -exec
работать, когда -type f
будет true. И поскольку grep
возвращает 0
(успех/истина), когда -exec grep "something"
есть совпадение, -quit
будет запущен.
решение2
find -type f | xargs grep e | head -1
делает именно это: когда head
завершается, средний элемент канала уведомляется сигналом «сломанной трубы», завершается в свою очередь и уведомляет find
. Вы должны увидеть уведомление, например,
xargs: grep: terminated by signal 13
что подтверждает это.
решение3
Чтобы сделать это без смены инструментов: (я люблю xargs)
#!/bin/bash
find . -type f |
# xargs -n20 -P20: use 10 parallel processes to grep files in batches of 20
# grep -m1: show just on match per file
# grep --line-buffered: multiple matches from independent grep processes
# will not be interleaved
xargs -P10 -n20 grep -m1 --line-buffered "$1" 2> >(
# Error output (stderr) is redirected to this command.
# We ignore this particular error, and send any others back to stderr.
grep -v '^xargs: .*: terminated by signal 13$' >&2
) |
# Little known fact: all `head` does is send signal 13 after n lines.
head -n 1