【问题标题】:Find and replace with sed in directory and sub directories在目录和子目录中查找并替换为 sed
【发布时间】: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 搜索苹果,但什么也没找到。它们都被替换了。 ;) 谢谢 。你睁开了我的眼睛!!!

标签: linux command-line sed replace


【解决方案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,这个答案是 stackoverflow.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 上,接受的答案确实有效 [种类] - 但它使用 -e 吐出“重复”文件,需要将其删除/通过管道传输到另一个命令(逐字使用)。这种方法虽然更好,但仍然对我有用(在 11.2.3 上)
【解决方案3】:

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

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获得。
      猜你喜欢
      • 2012-02-13
      • 1970-01-01
      • 1970-01-01
      • 2016-10-27
      • 1970-01-01
      • 2015-06-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多