在目录和子目录中查找并替换为 sed
Posted
技术标签:
【中文标题】在目录和子目录中查找并替换为 sed【英文标题】:Find and replace with sed in directory and sub directories 【发布时间】:2011-10-09 04:38:39 【问题描述】:我运行此命令在我站点根目录的所有文件中查找所有出现的“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 搜索苹果,但什么也没找到。它们都被替换了。 ;) 谢谢 。你睁开了我的眼睛!!!
【参考方案1】:
您的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,这个答案是 ***.com/questions/19242275/… RE error: illegal byte sequence
对于 fish shell 用户,一定要引用空括号''
,因为如果没有引用,fish 会自动扩展空括号。【参考方案2】:
由于也有 macOS 人在阅读这篇文章(和我一样),因此以下代码对我有用(在 10.14 上)
egrep -rl '<pattern>' <dir> | xargs -I@ sed -i '' 's/<arg1>/<arg2>/g' @
使用 -i
和 -e
的所有其他答案在 macOS 上均无效。
Source
【讨论】:
在 Mac 上,接受的答案确实有效 [种类] - 但它使用我认为我们可以用一行简单的命令来做到这一点
for i in `grep -rl eth0 . 2> /dev/null`; do sed -i ‘s/eth0/eth1/’ $i; done
请参阅此page。
【讨论】:
【参考方案4】:grep -e apple your_site_root/**/*.* -s -l | xargs sed -i "" "s|apple|orage|"
【讨论】:
【参考方案5】:在 linux 操作系统中:
sed -i 's/textSerch/textReplace/g' namefile
如果“sed”不起作用,请尝试:
perl -i -pe 's/textSerch/textReplace/g' namefile
【讨论】:
他要查找子目录中包含该字符串的所有文件并替换,而不仅仅是单个文件【参考方案6】:对于较大的 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'
【参考方案7】:
这对我有用:
find ./ -type f -exec sed -i '' 's#NEEDLE#REPLACEMENT#' *.php \;
【讨论】:
原始问题不限于 *.php 文件,还有一个 .ini 文件 未引用的*.php
确实不正确;您很幸运,它没有在起始目录中展开,因为那里没有任何匹配的文件。
文件名限制可以通过find
命令上的-name *.php
获得。以上是关于在目录和子目录中查找并替换为 sed的主要内容,如果未能解决你的问题,请参考以下文章