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

hd.*_*hd. 224 linux command-line replace sed

我运行此命令在我的站点的根目录中的所有文件中查找并替换所有出现的'apple'和'orange':

find ./ -exec sed -i 's/apple/orange/g' {} \;
Run Code Online (Sandbox Code Playgroud)

但它不会通过子目录.

这个命令有什么问题?

编辑:这是find ./命令的一些输出行:

./index.php
./header.php
./fpd
./fpd/font
./fpd/font/desktop.ini
./fpd/font/courier.php
./fpd/font/symbol.php
Run Code Online (Sandbox Code Playgroud)

jfg*_*956 392

您的查找应该是这样的,以避免将目录名称发送到sed:

find ./ -type f -exec sed -i -e 's/apple/orange/g' {} \;
Run Code Online (Sandbox Code Playgroud)

  • 实际上添加`-e`在Mac OS上不起作用.`touch abcde`后跟上面的命令产生一个如下目录列表:`a ae b be c ce d de e ee`. (19认同)
  • 您可能需要将`sed -i's/apple/orange/g'`更改为`sed -i''s/apple/orange/g'`才能使其正常工作. (16认同)
  • `-i`接受一个参数:用于保存临时文件的扩展名.在GNU sed中,看起来`-i`和它的参数之间没有空格,但是在BSD sed中有......所以BSD`-i''s/foo/bar /'`相当于GNU`-i' /富/酒吧/`. (6认同)
  • 对于Mac OS,这回答了http://stackoverflow.com/questions/19242275/re-error-illegal-byte-sequence-on-mac-os-x`RE错误:非法字节序列 (5认同)
  • 有人可以解释一下什么是 -exec 和 {} \; 在最后? (4认同)
  • 对于鱼壳用户,请务必引用空括号```'{''``,因为如果没有引用,鱼会自动扩展空括号. (2认同)

Jul*_*ius 78

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

grep -rl 'apples' /dir_to_search_under | xargs sed -i 's/apples/oranges/g'
Run Code Online (Sandbox Code Playgroud)

  • 谢谢你的回答,非常有帮助!如果在git存储库中,使用`git grep -l'apples'|会更快 xargs sed -i's/apples/oranges/g'` (18认同)
  • 如果在 Macos 上,请使用 `xargs sed -i '' 's/apples/oranges/g'` (2认同)
  • 如果您尝试用正斜杠替换某些内容,可以将 `sed` 与 `|` 一起使用,而不是使用 `/`,例如 `... xargs sed -i 's|mduuid/apples|mduuid/oranges |g'` /sf/ask/2850047931/ (2认同)

pat*_*t-s 14

由于也有 macOS 人员阅读了这篇文章(就像我一样),因此以下代码对我有用(在 10.14 上)

egrep -rl '<pattern>' <dir> | xargs -I@ sed -i '' 's/<arg1>/<arg2>/g' @
Run Code Online (Sandbox Code Playgroud)

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

来源


小智 5

这对我有用:

find ./ -type f -exec sed -i '' 's#NEEDLE#REPLACEMENT#' *.php {} \;
Run Code Online (Sandbox Code Playgroud)

  • 未加引号的`*.php`确实不正确;您很幸运,它没有在起始目录中扩展,因为那里碰巧没有任何匹配的文件。 (2认同)
  • 对文件名的限制可以通过“find”命令中的“-name *.php”来获得。 (2认同)