我想找到一个 bash 命令,它可以让我 grep 目录中的每个文件,并将该 grep 的输出写入一个单独的文件。我的猜测是做这样的事情

ls -1 | xargs -I{} "grep ABC '{}' > '{}'.out"

但是,据我所知, xargs 不喜欢双引号。但是,如果我删除双引号,则该命令会将整个命令的输出重定向到名为 '{}'.out 的单个文件,而不是一系列单独的文件。

有谁知道使用 xargs 执行此操作的方法吗?我只是使用这个 grep 场景作为示例来说明我的 xargs 问题,因此任何不使用 xargs 的解决方案都不适合我。

有帮助吗?

解决方案

不要犯这样的错误:

sh -c "grep ABC {} > {}.out"

这在很多情况下都会崩溃,包括时髦的文件名,并且不可能正确引用。你的 {} 必须始终是命令的一个完全独立的参数,以避免代码注入错误。你需要做的是:

xargs -I{} sh -c 'grep ABC "$1" > "$1.out"' -- {}

适用于 xargsfind.

顺便说一句,如果没有 -0 选项(除非是非常罕见且受控的一次性交互使用,您不担心会破坏数据)。

也不解析 ls. 。曾经。使用通配符或 find 反而: http://mywiki.wooledge.org/ParsingLs

使用 find 对于需要递归的所有内容和一个简单的循环,以及用于其他所有内容的 glob:

find /foo -exec sh -c 'grep "$1" > "$1.out"' -- {} \;

或非递归:

for file in *; do grep "$file" > "$file.out"; done

注意引号的正确使用。

其他提示

一个解决方案没有 xargs 如下:

find . -mindepth 1 -maxdepth 1 -type f -exec sh -c "grep ABC '{}' > '{}.out'" \;

...同样可以做到 xargs, ,事实证明:

ls -1 | xargs -I {} sh -c "grep ABC '{}' > '{}.out'"

编辑: :备注后添加单引号 卢纳特.

我想你的例子仅仅是个例子,你可能需要>其他东西。 GNU并行 http://www.gnu.org/software/parallel/ 可能是你的救援。它不需要额外的报价只要你的文件名不包含\ N:

ls | parallel "grep ABC {} > {}.out"

如果你有\ n的文件名在它:

find . -print0 | parallel -0 "grep ABC {} > {}.out"

作为额外的奖励,你得到的作业并行运行。

编辑。

可以安装GNU并行简单地通过:

wget http://git.savannah.gnu.org/cgit/parallel.git/plain/src/parallel
chmod 755 parallel

观看介绍视频了解详情: http://pi.dk/1

10秒安装:

wget pi.dk/3 -qO - | sh -x
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top