shell 希望在find命令中重定向grep命令的结果(find -exec)[已关闭]

iezvtpos  于 2022-11-16  发布在  Shell
关注(0)|答案(2)|浏览(172)

**已关闭。**此问题为not about programming or software development。目前不接受答案。

此问题似乎与a specific programming problem, a software algorithm, or software tools primarily used by programmers无关。如果您认为此问题与another Stack Exchange site相关,您可以留下评论,说明在何处可以找到此问题的答案。
27天前关闭。
截至27天前,机构群体正在审查是否重新讨论此问题。
Improve this question
我正在使用find命令搜索以.err和. out结尾的目录中的所有文件。我正在使用-exec和grep搜索文件中的一些内容。但是我不知道如何将每个grep命令重定向到一个文件。
这是我的命令:

find ./Documents/ -type f \( -name "*.out" -o -name "*.err" \) -exec sh -c "grep out {}; grep err {}" \;

我已经尝试过此操作,但它不起作用(创建的文件为空):

find ./Documents/ -type f \( -name "*.out" -o -name "*.err" \) -exec sh -c "grep out > file1 {}; grep err > file2 {}" \;

我怎样才能解决这个问题?

t8e9dugd

t8e9dugd1#

传统的语法是grep pattern inputfile >outputfile,所以这就是我的建议。
但是,您也应该避免将{}放在-exec sh -c '...'中,因为如果文件名包含shell元字符,它将中断。您正在单引号中创建一个新的shell,在该脚本中,带有单引号的文件名需要进行转义或其他处理。
幸运的是,解决方法很简单;包含这些字符的变量就可以了(但您还需要对变量interpolation使用双引号!)
我还猜测您不希望每次find找到新文件时都覆盖以前-exec的结果,因此我将>更改为>>

find ./Documents/ -type f \( \
    -name "*.out" -o -name "*.err" \) \
    -exec sh -c 'grep out "$1">>file1
        grep err "$1" >>file2
        ' _ {} \;

另一个改进是使用-exec ... {} +为尽可能多的文件运行单个-exec;然后需要向内部脚本添加一个循环。

find ./Documents/ -type f \( \
    -name "*.out" -o -name "*.err" \) \
    -exec sh -c 'for f; do
        grep out "$f">>file1
        grep err "$f">>file2
    done' _ {} +

根据您的用例,您可能能够摆脱循环,直接在所有文件上运行grep

find ./Documents/ -type f \( \
    -name "*.out" -o -name "*.err" \) \
    -exec sh -c '
        grep -H out "$@">>file1
        grep -H err "$@">>file2
    ' _ {} +

-H选项关闭每个匹配项的文件名报告,如果对多个文件运行grep,则默认情况下将启用该选项。
另请参阅When to wrap quotes around a shell variable?https://mywiki.wooledge.org/BashFAQ/020

mo49yndu

mo49yndu2#

grep命令中的顺序不对。您还应该使用'〉〉'重定向到append。否则您之前的grep输出将被find命令找到的下一个文件覆盖。
请尝试以下命令:

find ./Documents/ -type f \( -name "*.out" -o -name "*.err" \) -exec sh -c "grep 'out' {} >> file1; grep 'err' {} >> file2" \;

相关问题