【问题标题】:Replace text in multiple file extentions替换多个文件扩展名中的文本
【发布时间】:2014-06-21 14:58:43
【问题描述】:

我正在尝试使用 sed 替换多个文件中的一些文本。

例如:在一个目录及其子目录中的所有 txt 和 md 文件中,将 lion 替换为 hawk

到目前为止,我从研究中得到的最好的(非工作)尝试是:

find . -type *.txt | xargs sed -i '' 's/lion/hawk/'

还尝试将 md 添加到 txt 正则表达式 - *\.(txt|md) 会出错。

提前感谢您的帮助。

【问题讨论】:

    标签: regex sed


    【解决方案1】:

    你想要

    find . -type f \( -name '*.txt' -o -name '*.md' \) -exec sed -i 's/lion/hawk/g' {} \;
    

    -o 是两个-name 谓词的逻辑或。您也可以直接使用-exec 而不是通过管道连接到xargs(两者都可以)。

    编辑更新了引用和括号。

    【讨论】:

    • +1 但是使用+而不是\;会更有效,因为它会一次将多个文件发送到sed,因此调用它的频率较低。
    • 请注意,从性能角度来看,find -execxargs 差得多 - 它会为找到的每个文件执行新的 sed 实例,而 xargs 会将许多文件组合成单个 sed打电话
    • @beer 它对我不起作用。它仅替换 .md 中的字符串 lion 而不是 .txt 文件中的字符串。
    • @mvp 我假设您的意思是名称匹配不正确,但正在放弃您关于-exec 效率低于xargs 的错误说法。好的。
    • @beerbajay 您需要在文件名模式周围加上单引号,这样它们就不会被 shell 扩展。你应该用+ 替换最后的\; 以提高效率。见gnu.org/software/findutils/manual/html_node/find_html/…
    【解决方案2】:

    这应该适合你:

    find . -type f -regextype egrep -regex ".*\.(txt|md)" -print0 | xargs -0 sed -i '' 's/lion/hawk/'
    

    与您的尝试的重要区别:

    • 使用-type f 将搜索限制为仅文件
    • 使用-regextype 将正则表达式引擎设置为egrep(比默认的emacs 更智能)
    • 使用-regex ".*\.(txt|md)" 将搜索限制为具有txtmd 扩展名的文件
    • 使用find -print0xargs -0 正确处理文件名中的空格

    【讨论】:

      【解决方案3】:

      试试下面的 GNU find 命令,

      find . -name *.txt -o -name *.md -type f | xargs sed -i 's/lion/hawk/g'
      

      说明:

      .                              #  Current directory
      
      -name *.md -o -name *.md       # Filenames end with .txt or .md
      -type f                        #   Only files.
      xargs sed -i 's/lion/hawk/g'    #  Replace lion with hawk on the founded files.
      

      【讨论】:

      • 看来你误会了mindepthfind 的默认行为是查看子目录。 mindepth 用于将操作限制在至少那么深的深度。
      • @ooga 感谢您的信息。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-10
      相关资源
      最近更新 更多