代码之家  ›  专栏  ›  技术社区  ›  Jesse Shieh José Valim

如何在xargs命令中使用>?

  •  138
  • Jesse Shieh José Valim  · 技术社区  · 16 年前

    我想找到一个bash命令,它允许我对目录中的每个文件进行grep,并将grep的输出写到一个单独的文件中。我想应该是做这样的事

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

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

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

    3 回复  |  直到 7 年前
        1
  •  167
  •   lhunath    7 年前

    不要犯这样的错误:

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

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

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

    适用于 xargs 以及 find .

    顺便说一下,在没有 -0 选项(除非用于非常罕见且受控的一次性交互使用,在这种情况下,您不必担心破坏数据)。

    也不要解析 ls . 曾经。使用球形或 找到 而是: http://mywiki.wooledge.org/ParsingLs

    使用 找到 对于所有需要递归的内容,以及一个简单的循环,其中包含一个用于其他内容的glob:

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

    或非递归:

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

    注意引号的正确使用。

        2
  •  37
  •   Tudor Timi    7 年前

    没有的解决方案 xargs 如下所示:

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

    …也可以这样做 具有 参数代换 结果证明:

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

    编辑 :在备注后添加单引号 lhunath .

        3
  •  14
  •   Ole Tange    12 年前

    我假设您的示例只是一个示例,您可能需要其他东西。GNU并行 http://www.gnu.org/software/parallel/ 可能是你的救星。只要文件名不包含以下内容,就不需要额外报价:

    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