bash find xargs grep только единичное вхождение

bash find xargs grep только единичное вхождение

Может быть, это немного странно, и, возможно, есть другие инструменты, позволяющие это сделать, но, ну...

Я использую следующую классическую команду 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

Связанный контент