ChatGPT解决这个技术问题 Extra ChatGPT

在目录和子目录中查找并替换为 sed

我运行此命令以在我的站点根目录中的所有文件中查找所有出现的“apple”并将其替换为“orange”:

find ./ -exec sed -i 's/apple/orange/g' {} \;

但它不通过子目录。

这个命令有什么问题?

以下是 find ./ 的一些输出行:

./index.php
./header.php
./fpd
./fpd/font
./fpd/font/desktop.ini
./fpd/font/courier.php
./fpd/font/symbol.php
您可以运行 find ./ 并发布一些示例输出吗?和目录结构请。编辑:谢谢!
嗯,你的发现是正确的,适用于我的子目录。
你怎么知道它不处理子目录?
因为它给出了以下错误: sed:无法编辑 ./fpd:不是常规文件 sed:无法编辑 ./fpd/font:不是常规文件 sed:无法编辑 ./fpd/font/makefont:不是规则
哦...我用 grep 搜索苹果,但什么也没找到。它们都被替换了。 ;) 谢谢你 。你睁开了我的眼睛!!!

P
Philippe Fanaro

您的 find 应如下所示以避免将目录名称发送到 sed

find ./ -type f -exec sed -i -e 's/apple/orange/g' {} \;

您可能需要将 sed -i 's/apple/orange/g' 更改为 sed -i '' 's/apple/orange/g' 才能完成这项工作。
-i 接受一个参数:用于保存临时文件的扩展名。在 GNU sed 中,-i 与其参数之间似乎没有空格,但在 BSD sed 中有……所以 BSD -i '' 's/foo/bar/' 等同于 GNU -i 's/foo/bar/
实际上添加 -e 在 Mac OS 上不起作用。 touch a b c d e 后跟上面的命令会生成如下目录列表:a a-e b b-e c c-e d d-e e e-e
对于 Mac OS,这回答了 stackoverflow.com/questions/19242275/… RE error: illegal byte sequence
对于fish shell 用户,一定要引用空括号'{}',因为如果没有引用,fish 会自动扩展空括号。
J
Julius

对于较大的 s&r 任务,使用 grep 和 xargs 会更好更快,例如;

grep -rl 'apples' /dir_to_search_under | xargs sed -i 's/apples/oranges/g'

感谢您的回答,非常有帮助!如果在 git 存储库中,使用 git grep -l 'apples' | xargs sed -i 's/apples/oranges/g' 会更快
如果在 macOS 上,请使用 xargs sed -i '' 's/apples/oranges/g'
如果您尝试用正斜杠替换某些内容,您可以使用 sed| 而不是 /,例如 ... xargs sed -i 's|mduuid/apples|mduuid/oranges|g' stackoverflow.com/questions/40714970/…
p
pat-s

由于也有 macOS 人在阅读这个(就像我一样),所以下面的代码对我有用(在 10.14 上)

egrep -rl '<pattern>' <dir> | xargs -I@ sed -i '' 's/<arg1>/<arg2>/g' @

使用 -i-e 的所有其他答案都不适用于 macOS。

Source


在 Mac 上,接受的答案确实有效 [种类] - 但它会吐出带有 -e 的“重复”文件,需要将其删除/传送到另一个命令中(以逐字使用)。这种方法虽然更好,但仍然对我有用(在 11.2.3 上)
s
shadyyx

这对我有用:

find ./ -type f -exec sed -i '' 's#NEEDLE#REPLACEMENT#' *.php {} \;

原始问题不限于 *.php 文件,还有一个 .ini 文件
未引用的 *.php 确实不正确;您很幸运,它没有在起始目录中扩展,因为您碰巧在那里没有任何匹配的文件。
可以使用 find 命令上的 -name *.php 获得对文件名的限制。
r
rocLv
grep -e apple your_site_root/**/*.* -s -l | xargs sed -i "" "s|apple|orage|"

B
Billal Begueradj

我认为我们可以用一行简单的命令来做到这一点

for i in `grep -rl eth0 . 2> /dev/null`; do sed -i ‘s/eth0/eth1/’ $i; done

请参阅此page


C
Colin D

为此找到了一个很棒的程序,名为 ruplacer

https://github.com/dmerejkowsky/ruplacer

用法

ruplacer before_text after_text # prints out list of things it will replace
ruplacer before_text after_text --go # executes the replacements

它还尊重 .gitignore,因此它不会弄乱您的 .gitnode_modules 目录(默认情况下 find . 将进入您的 .git 目录并可能损坏它!!!)


ฉัตรชัย สิทธิวงค์

在 Linux 操作系统中:

sed -i 's/textSerch/textReplace/g' namefile

如果“sed”不起作用,请尝试:

perl -i -pe 's/textSerch/textReplace/g' namefile

他想查找子目录中的所有文件都包含该字符串并替换,而不仅仅是单个文件