bash find xargs grep 只出现一次

hel*_*rth 17 grep bash find xargs

也许这有点奇怪 - 也许还有其他工具可以做到这一点,但是,好吧..

我正在使用以下经典 bash 命令来查找包含一些字符串的所有文件:

find . -type f | xargs grep "something"
Run Code Online (Sandbox Code Playgroud)

我在多个深度上有大量文件。第一次出现“某事”对我来说已经足够了,但 find 会继续搜索,并且需要很长时间才能完成其余的文件。我想做的是类似于从 grep 返回到 find 的“反馈”,以便 find 可以停止搜索更多文件。这样的事情可能吗?

Che*_*evy 20

只需将其保持在 find 的范围内:

find . -type f -exec grep "something" {} \; -quit
Run Code Online (Sandbox Code Playgroud)

这是它的工作原理:

-exec会工作时,-type f会是真的。并且因为在匹配时grep返回0(成功/真)-exec grep "something",所以-quit将被触发。


Kil*_*oth 8

find -type f | xargs grep e | head -1
Run Code Online (Sandbox Code Playgroud)

正是这样做的:当head终止时,管道的中间元素会收到一个“管道损坏”信号,依次终止,并通知find. 您应该会看到一条通知,例如

xargs: grep: terminated by signal 13
Run Code Online (Sandbox Code Playgroud)

这证实了这一点。


buk*_*zor 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
Run Code Online (Sandbox Code Playgroud)