链接 find exec 和 while 循环

链接 find exec 和 while 循环

我正在尝试堆叠一个 find 命令,以便它返回的结果仅包含其中包含“警告:”或“错误:”文本的文件。我还需要特定格式的这些结果,因此我正在使用exec stat它。

我可以获得一个可以工作的版本,但我需要能够-exec stat在 while 循环中使用来制定特定的字符串,这-exec stat使我的 shell 向我提供>提示。不起作用的部分在下面以粗体显示。

我可以单独让这些工作。在一起我不能。

这是我正在工作的一个例子:

find . -type f -exec grep -li error: {} \; | while read -r file; do ls -l "$file"; done

所以现在我试图将其与另一个将文件限制为特定时间、类型等的过程进行硬塞。进展并不顺利:

找到 /my/directory/here/ -type f -name *.log -mmin -480 -mmin +60 -exec grep -li 警告:{} \; -exec grep -li 错误:{} \;|当读取-r文件时; do -exec stat -c "$file" '%n|%y|%x|%s|%U|%u' {} \;完毕

-exec stat请注意,如果我从 while 循环中删除,整个事情就会起作用。如果我用一个简单的替换它ls -l,结果就会返回给我。现在 shell 只是给我一个命令提示符。

我知道我做得不对,但我现在不知道我应该首先解决什么。

答案1

find /my/directory/here/ -type f -name '*.log' -mmin -480 -mmin +60 \
    -exec grep -qi warning: {} \; \
    -exec grep -qi error: {} \; \
    -exec stat -c '%n|%y|%x|%s|%U|%u' {} +

也就是说,您不需要这两个grep命令的实际输出,只需要退出状态,因此我们使用-q而不是-l.不需要循环while。可能stat会被多个文件调用,所以我们使用-exec stat ... {} +.我还引用了该*.log模式以防止其扩展到当前目录中的任何此类名称。

有关的:

做同样事情的另一种方法:

find /my/directory/here/ -type f -name '*.log' -mmin -480 -mmin +60 \
    -exec sh -c '
        for pathname do
            if grep -qi warning: "$pathname" &&
               grep -qi error: "$pathname"
            then
                stat -c "%n|%y|%x|%s|%U|%u" "$pathname"
            fi
        done' sh {} +

它用作在子 shell 中运行的循环find的路径名生成器。for然而,这将为stat包含两种模式的匹配的每个文件调用一次,因此效率稍低。

答案2

GNU 的 grep(1) 可以进行递归模式匹配:

grep -R warning that-dir

检查 . 下的所有文件that-dir

相关内容