2011-11-21 84 views
14

我在Bash是全新的,但我似乎无法找到一种方法让它按照我想要的方式工作。BASH:递归程序替换文件树中的文本

假设你有一个树形目录有2个文件: /top.php和/test/bottom.php

如何让我的函数查找和替换说“你好”到“卓悦”在/顶.php AND在/test/bottom.php?

到目前为止,我发现做到这一点的唯一方法是通过用不同深度级别调用同一个函数两次:

find ./*.php -type f -exec sed -i 's/hello/bonjour/' {} \; 
find ./*/*.php -type f -exec sed -i 's/hello/bonjour/' {} \; 

肯定有一个递归的方式在一行做到这一点?

+0

可能[awk/sed的重复:如何做一个recursi找到/替换一个字符串?](http://stackoverflow.com/questions/1583219/awk-sed-how-to-do-a-recursive-find-replace-of-a-string) – Pureferret

回答

36

使用一个实际的模式来发现,而不是外壳通配符扩展:

find . -name '*.php' -type f -exec sed -i 's/hello/bonjour/' {} \; 
+0

你的工作完美!如果可以的话,我会加倍努力,但是我没有所需的声望 – Audioy

+1

@Erken:谢谢。您应该有信誉接受答案(投票数下面的复选标记)。无论如何,这是正确的回应:-)。 – thiton

+0

完美,明白了!非常感谢你们,你们已经非常快! oO – Audioy

-2

使用xargs的和grep:

find . -type f | grep php$ | xargs -n1 -i sed -i 's/hello/bonjour/' {} 

下面是它如何工作的:

找到所有文件和 - 当前目录:

find . -type f 

只包括那些在php结尾的文件:

grep php$ 

每次取线,并应用SED它:

xargs -n1 -i sed -i 's/hello/bonjour/' {} 
+2

,但它不起作用(考虑带空格的文件名) – sehe

+0

首先,不要在您的文件名中放置空格! :)其次,只需引用 - 附上“{}”部分,你应该没问题。 –

+3

没有。 Grep/xargs会杀死你的小猫。 – sehe

2

关闭:

find -iname '*.php' -type f -exec sed -i 's/hello/bonjour/' {} \; 

或者

find -iname '*.php' -type f -print0 | 
    xargs -0 sed -i 's/hello/bonjour/' 
+0

你提供的第一个解决方案没有奏效。我还没有尝试第二个,但thiton给出的解决方案更直接 – Audioy

+0

@Erken:那是因为在顶层目录中的文件比描述的问题多。学会引用你的通配符,如果你不希望它们扩大。 – sehe

+0

Gotcha!感谢sehe – Audioy