【问题标题】:Find and xargs to correctly handle filenames with spaces in their namesFind 和 xargs 以正确处理名称中带有空格的文件名
【发布时间】:2021-07-09 03:11:52
【问题描述】:

目前我使用以下代码在当前文件夹下的任何.php 文件中搜索和替换字符串。

find . -name "*.php" -print | xargs sed -i 's/string1/string2/g'

但是当它遇到文件名中带有空格的文件时,它会抛出No such file or directory 的错误。我将如何修改这一行以包含带空格的文件?

我假设find 命令的输出必须在文件路径周围输出双引号,但我自己不知道如何编写。

【问题讨论】:

    标签: linux bash


    【解决方案1】:
    find . -name "*.php" -print0 | xargs -0 sed -i 's/string1/string2/g'
    

    你也可以完全不使用 xargs:

    find . -name "*.php" -execdir sed -i 's/string1/string2/g' {} +
    

    【讨论】:

    • execdir 优于 exec 以避免竞争条件,至少在 GNU 的实现中,手册页推荐前者。
    • @legends2k:你是对的(至少对于 OP 似乎正在使用的 Linux)。我更新了我的答案。谢谢。
    【解决方案2】:

    如果您在互动工作的一部分(而不是在某些脚本内 - 请参阅限制)执行此操作,您可能会发现以下内容也很方便:

    shopt -s globstar  #best add to into ~/.bash_profile
    sed -i 's/string1/string2/g' ./**/*.php
    

    限制:所有路径名的总长度不能更长,因为返回 getconf ARG_MAX 命令。在我的系统上 262144 字节 - 例如大约 6500 个文件,例如 ./somedir/subdir/subsubdir/filename.php - 足以应付日常的互动工作...

    【讨论】:

      【解决方案3】:

      如果你有 GNU Parallel,你可以这样做:

      find . -name "*.php" -print | parallel -q sed -i 's/string1/string2/g'
      

      如果您想在将文件名传递给并行之前处理它们,这将很有用。例如。使用tail:

      find . -name "*.php" -print | tail -n 11 | parallel -q sed -i 's/string1/string2/g'
      

      (仅当字符串包含特殊字符时才需要-q - 例如空格)。

      所有新计算机都有多个内核,但大多数程序本质上是串行的,因此不会使用多个内核。然而,许多任务是极其可并行化的:

      • 对多个文件运行相同的程序
      • 为文件中的每一行运行相同的程序
      • 为文件中的每个块运行相同的程序

      GNU Parallel 是一种通用的并行化器,可以轻松地在同一台机器上或在您可以通过 ssh 访问的多台机器上并行运行作业。

      如果您想在 4 个 CPU 上运行 32 个不同的作业,那么并行化的直接方法是在每个 CPU 上运行 8 个作业:

      GNU Parallel 会在完成后生成一个新进程 - 保持 CPU 处于活动状态,从而节省时间:

      安装

      如果没有为您的发行版打包 GNU Parallel,您可以进行个人安装,这不需要 root 访问权限。这样做可以在 10 秒内完成:

      $ (wget -O - pi.dk/3 || lynx -source pi.dk/3 || curl pi.dk/3/ || \
         fetch -o - http://pi.dk/3 ) > install.sh
      $ sha1sum install.sh | grep 883c667e01eed62f975ad28b6d50e22a
      12345678 883c667e 01eed62f 975ad28b 6d50e22a
      $ md5sum install.sh | grep cc21b4c943fd03e93ae1ae49e28573c0
      cc21b4c9 43fd03e9 3ae1ae49 e28573c0
      $ sha512sum install.sh | grep da012ec113b49a54e705f86d51e784ebced224fdf
      79945d9d 250b42a4 2067bb00 99da012e c113b49a 54e705f8 6d51e784 ebced224
      fdff3f52 ca588d64 e75f6033 61bd543f d631f592 2f87ceb2 ab034149 6df84a35
      $ bash install.sh
      

      有关其他安装选项,请参阅http://git.savannah.gnu.org/cgit/parallel.git/tree/README

      了解详情

      查看更多示例:http://www.gnu.org/software/parallel/man.html

      观看介绍视频:https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1

      浏览教程:http://www.gnu.org/software/parallel/parallel_tutorial.html

      注册电子邮件列表以获得支持:https://lists.gnu.org/mailman/listinfo/parallel

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-05-21
        • 2012-11-29
        • 2012-12-12
        • 2011-07-09
        • 2018-09-24
        • 2012-04-07
        相关资源
        最近更新 更多