unix查找并替换dir和subdirs中的文本

时间:2012-01-18 19:36:59

标签: perl unix sed grep replace

我正在尝试在给定主目录和子目录中的所有文档中将“my-silly-home-page-name.html”的名称更改为“index.html”。

我看到了这个:Shell script - search and replace text in multiple files using a list of strings

而且:How to change all occurrences of a word in all files in a directory

我试过这个:

grep -r "my-silly-home-page-name.html" .

这会找到文本所在的行,但现在我想用'my-silly-home-page-name'代替'index'。 我怎么用sed或perl做这个? 或者我甚至需要sed / perl?

类似的东西:

grep -r "my-silly-home-page-name.html" . | sed 's/$1/'index'/g'

也;我正在尝试使用perl,我尝试以下方法:

perl -i -p -e 's/my-silly-home-page-name\.html/index\.html/g' *

这样可行,但是当perl遇到目录时出现错误,说“无法进行就地编辑:SOMEDIR-NAME不是常规文件,<>行N”

谢谢, JML

3 个答案:

答案 0 :(得分:7)

find . -type f -exec \
   perl -i -pe's/my-silly-home-page-name(?=\.html)/index/g' {} +

或者,如果您的find不支持-exec +

find . -type f -print0 | xargs -0 \
   perl -i -pe's/my-silly-home-page-name(?=\.html)/index/g'

两者都尽可能多地传递给Perl作为参数。两者都可以使用任何文件名,包括那些包含换行符的文件名。


如果您使用的是Windows并且使用的是Perl的Windows版本(而不是cygwin版本),则-i将不起作用,除非您还对原始版本进行备份。将-i更改为-i.bak。然后,您可以使用

删除备份
find . -type f -name '*.bak' -delete

答案 1 :(得分:1)

这应该做的工作:

find . -type f -print0 | xargs -0 sed -e 's/my-silly-home-page-name\.html/index\.html/g' -i

基本上,它使用.以递归方式收集给定目录(示例中为find)的所有文件,并使用与sed中相同的替换命令运行perl通过xargs在问题中命令。

关于sedperl的问题,我会说你应该使用你更熟悉的那个,因为我不期望有很大的差异(替换命令是毕竟是同一个。)

答案 2 :(得分:0)

可能有更好的方法可以使用:

find . -name oldname.html |perl -e 'map { s/[\r\n]//g; $old = $_; s/oldname.txt$/newname.html/; rename  $old,$_  } <>';

Fyi, grep 搜索模式; 查找 搜索文件。