2012-01-18 231 views
1

我试图在给定主目录和子目录中的所有文档中将“my-silly-home-page-name.html”的名称更改为“index.html” 。unix在目录和子目录中查找和替换文本

我看到了这个: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" . 

这个发现在其上文字存在的线,但现在我想代替“我傻,家庭PAGE-名称'为'索引'。 我如何使用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

+0

可能的重复:http://stackoverflow.com/questions/8905662/how-to-change-all-occurances-of-a-word-in-all- files-in-a-directory/ – 2012-01-18 19:41:01

+0

我也在问一个关于perl的问题,一般来说,进入另一种方法的好处是什么。 – jml 2012-01-18 19:47:26

+0

我也特别想知道有关目录的perl问题的解决方案... – jml 2012-01-18 19:50:14

回答

6
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 
+0

,它工作得更好(至少它写入更多的文件),但我仍然得到关于“无法就地编辑”的错误。 – jml 2012-01-18 19:58:45

+0

@jml,更新了我对地址“无法就地编辑”的答案。 – ikegami 2012-01-18 20:04:40

+0

谢谢。非常感激! – jml 2012-01-18 20:20:23

1

这应该做的工作:

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

基本上它递归集人l来自给定目录(示例中为.)的文件为find,并运行sed,其中中的问题与perl命令中的命令具有相同的替换命令。

关于sedperl的问题,我想说你应该使用一个更舒服的问题,因为我不期望有很大的差异(替代命令毕竟是相同的)。

0

可能有更好的方法来做到这一点,但你可以使用:

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

据透露,grep的搜索模式; 找到搜索文件。

相关问题