【问题标题】:Find and replace text in files in all subdirectories [duplicate]在所有子目录中的文件中查找和替换文本[重复]
【发布时间】:2015-04-01 01:01:54
【问题描述】:

在 Mac 上;我正在使用 Hazel 运行 shell 脚本,以便在我的下载文件夹内的多个子目录中的 .txt 文件中查找和替换文本。 我的 script.sh 文件位于其他地方 (/Users/admin/Desktop)

script.sh 目前看起来像这样:

#!/bin/bash
cd /Users/admin/Downloads/
perl -pi -w -e 's/OldText/NewText/g;' *.txt

它可以工作,但不会查看下载中的所有子目录。我该怎么做?

【问题讨论】:

  • 接受答案中显示的相同逻辑也应应用于调用perl
  • 研究使用findxargs 将文件名提供给perl

标签: macos perl shell


【解决方案1】:

使用findxargs

类似于(未测试!):

find /Users/admin/Downloads/ -type f -print0 | xargs -0 perl -pi -w -e 's/OldText/NewText/g;' 

【讨论】:

    【解决方案2】:

    我不确定在这种情况下您为什么需要 perl,我不确定 Hazel 是谁以及她为什么会运行您的 shell 脚本,但是既然您已经标记了您的问题 shell 并且是显然使用bash,我将提供一个仅限外壳的答案。请注意,这也适用于其他 shell,而不仅仅是 bash。

    #!/bin/bash
    
    find /Users/admin/Downloads/ -type f -name "*.txt" \
      -exec sed -i '' -ne 's/OldText/NewText/g' {} \;
    

    请注意,此find 命令分为两行以便于阅读。它使用sed 而不是perl,因为sed 更小并且可能更快,并且被认为是标准的shell 工具,而perl 可能并非在所有系统上都可用。

    另请注意,我使用的 sed 选项的确切语法可能取决于您系统上的 sed 实现。

    find 命令的工作方式如下:

    find [path ...] [command ...]
    

    您可以man find查看详细信息,但我在此处提供的命令执行以下操作。

    • 开始于/Users/admin/Downloads/
    • -type f - 查找文件(而不是目录或符号链接)
    • -name "*.txt" - 并查找与此文件规范匹配的内容
    • -exec ... - AND 执行以下 shell 命令,将 {} 替换为找到的文件名。

    【讨论】:

    • 嗯。这删除了目录中我所有文件(具有指定结尾)的完整内容。
    • @Ixx - 我需要查看您的确切命令行才能告诉您原因。连同您的操作系统和/或sed 的版本。最有可能的是,您的 sed 脚本(或其中的 RE)不正确。请随时ask a question