如何在不改变所有权的情况下进行搜索和替换

时间:2010-04-09 19:10:26

标签: unix sed replace

我找到了这个命令行搜索并替换示例:

find . -type f -print0 | xargs -0 sed -i 's/find/replace/g'

它工作正常,除了它改变了搜索的每个文件的日期和文件所有权,甚至是那些不包含搜索文本的文件。

这项任务有什么更好的解决方案?

3 个答案:

答案 0 :(得分:4)

使用-c选项(如果你在Linux上)应该使sed保留所有权。当您使用该命令时,它实际上是重写每个文件,即使它没有对不包含find的文件进行更改。

答案 1 :(得分:3)

解决这个问题的最简单方法是,如果首先使用grep包含文本,则只对文件执行sed:

find . -type f | while read file; do
    grep -q find $file && sed -i 's/find/replace/g' $file
done

这确实需要两次读取每个文件(在最坏的情况下),因此它可能会慢一些。但是,希望您的操作系统应该将文件保留在其磁盘缓存中,因此您不应该看到太多的减速,因为这个过程肯定是I / O绑定的,而不是CPU限制的。

答案 2 :(得分:1)

某些发行版的sed(即RedHat和系列)添加了-c选项来完成此操作,在这种情况下请参阅@ Isaac的答案。

但对于那些没有修补GNU sed的人来说,我发现的最简单的方法就是简单地用perl替换,它会在可用时重写类似于sed -c的文件。以下命令基本等效:

sed -ci 's/find/replace/'
perl -pi -e 's/find/replace/'

不要太兴奋,做perl -pie;与sed -ie一样,它不会将其解释为另一个选项,而是使用e作为-i的参数,并将其用作备份原始文件的后缀。有关详细信息,请参阅perldoc perlrun

对于更复杂的事情,Perl的正则表达式解析与sed(更好的,imo)略有不同:一般来说,使用更少的反斜杠。