在所有子目录中查找和替换文件中的文本

4
在 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

它可以工作,但无法查找Downloads文件夹内的所有子目录。我该怎么做?

相同的逻辑应该也适用于调用 perl - legends2k
调查使用 findxargs 将文件名提供给 Perl。 - user648852
2个回答

3

使用 findxargs 来实现类似以下的功能(未经测试!):

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

1

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

#!/bin/bash

find /Users/admin/Downloads/ -type f -name "*.txt" \
  -exec sed -i '' -e '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 ... - 并执行以下shell命令,将{}替换为已找到的文件名。

4
哦。这将删除目录中所有以指定结尾的文件的完整内容。 - User
@Ixx - 我需要看到您的确切命令行,才能告诉您原因。以及您的操作系统和/或sed版本。很可能,您的sed脚本(或其中的RE)是不正确的。请随时提问 - ghoti
这也删除了我的文件的完整内容。使用“-ne”选项会导致此问题,去掉它就可以解决。执行命令如下:sed -i'' 's/OldText/NewText/g' {} ; - Nick Lothian
@NickLothian 和 @User .. 哇,我不敢相信那个错误已经存在了7年。问题只是 -n,它抑制输出,需要显式打印行。是的,在这种情况下不需要。我已经将其删除了。 - ghoti
@ghoti - 非常好,感谢您的更新。我发现这个答案很有用! - Nick Lothian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接