Bash найти XARGS grep только один случай

16

Может быть, это немного странно - и, возможно, есть другие инструменты, чтобы сделать это, но, хорошо ..

Я использую следующую классическую команду bash, чтобы найти все файлы, которые содержат некоторую строку:

find . -type f | xargs grep "something"

У меня есть большое количество файлов на разных глубинах. Первое появление «что-то» мне достаточно, но find продолжает поиск и занимает много времени, чтобы завершить остальные файлы. Я хотел бы сделать что-то вроде «обратной связи» от grep back для поиска, чтобы поиск мог прекратить поиск большего количества файлов. Это возможно?

hello_earth
источник

Ответы:

20

Просто держите это в пределах области поиска:

find . -type f -exec grep "something" {} \; -quit

Вот как это работает:

-execБудет работать , если -type fбудет верно. И потому что grepвозвращает 0(успех / истина), когда -exec grep "something"есть совпадение, -quitбудет срабатывать.

Чен Леви
источник
8
find -type f | xargs grep e | head -1

делает именно это: когда headзавершается, средний элемент канала уведомляется сигналом «сломанный канал», завершается по очереди и уведомляет find. Вы должны увидеть уведомление, такое как

xargs: grep: terminated by signal 13

что подтверждает это.

Килиан Фот
источник
+1 за объяснение и альтернативу, хотя другой ответ кажется мне более элегантным, поскольку он более самодостаточен
hello_earth
8

Чтобы сделать это без изменения инструментов: (Я люблю 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
bukzor
источник
1
+1 никогда не знал, что у xargs будут такие возможности многозадачности - спасибо за другие комментарии! :)
hello_earth