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


244

我运行以下命令以查找并替换网站根目录中所有文件中所有出现的“ 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 ./并发布一些示例输出吗?以及目录结构。编辑:谢谢!
雅各布

嗯,您的发现是正确的,可以通过subdirs为我工作。
雅各布

1
您怎么知道它不处理子目录?
卡尔皮特2011年

因为它会产生以下错误:sed:无法编辑./fpd:非常规文件sed:无法编辑./fpd/font:非常规文件sed:无法编辑./fpd/font/makefont:不是一个边条
HD。

哦...我为苹果准备了grep,没有发现任何东西。它们全部被替换了。;) 谢谢 。你睁开了我的眼睛!
hd。

Answers:


420

您的发现应该看起来像这样,以避免将目录名称发送到sed:

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

19
您可能需要改变sed -i 's/apple/orange/g',以sed -i '' 's/apple/orange/g'使这项工作。
paulmelnikow

7
-i接受一个参数:用于保存临时文件的扩展名。在GNU sed中,-i参数之间似乎没有空格,但是在BSD sed中存在……因此BSD -i '' 's/foo/bar/'等效于GNU -i 's/foo/bar/
paulmelnikow 2014年

20
实际上添加-e在Mac OS上不起作用。touch a b c d e接着上面的命令生成一个目录列表,如下所示:a a-e b b-e c c-e d d-e e e-e
paulmelnikow 2014年

6
对于Mac OS,这个答案stackoverflow.com/questions/19242275/...RE error: illegal byte sequence
kakoma

3
对于鱼壳用户,请确保用引号将空括号括起来'{}',因为如果未用引号,则fish会自动展开空括号。
凯文·谢泼斯基

84

对于较大的S&R任务,使用grep和xargs更好,更快。

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

20
感谢您的回答,它非常有帮助!如果在git存储库中,使用它甚至更快git grep -l 'apples' | xargs sed -i 's/apples/oranges/g'
mrodrigues

4

这为我工作:

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

原始问题不限于* .php文件,还有一个.ini文件
-knocte

未引用*.php的确实不正确;您只是很幸运,它没有在起始目录中得到扩展,因为您恰巧那里没有任何匹配的文件。
Tripleee '19

3
grep -e apple your_site_root/**/*.* -s -l | xargs sed -i "" "s|apple|orage|"

1

由于也有macOS的人正在阅读此书(就像我所做的那样),因此以下代码对我有用(在10.14上)

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

所有其他的答案使用-i,并-e没有在MacOS工作。

资源


0

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

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

请参阅此页面


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.