开发者

How to sed search and replace without changing ownership

I found this command line search and replace example:

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

It worked fine except it changed the date and file ownership on EVERY file it searched through, even those that did not contai开发者_运维知识库n the search text.

What's a better solution to this task?


Using the -c option (if you are on Linux) ought to cause sed to preserve ownership. As you are using the command, it is in fact rewriting every file, even though it is not making changes to the files that do not contain find.


The easiest way to fix that would be to only execute sed on the files if the contain the text by using grep first:

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

This does require reading each file twice (in the worst case), so it might be a little slower. Hopefully, though, your OS should keep the file in its disk cache, so you shouldn't see much of a slowdown, since this process is definitely I/O-bound, not CPU-bound.


Some distro's versions of sed (namely, RedHat and family) have added a -c option that accomplishes this, in which case see @Isaac's answer.

But for those with an unpatched GNU sed, the easiest way I've found is to simply substitute with perl, which rewrites files similar to sed -c when available. The following commands are basically equivalent:

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

Just don't get too excited and do perl -pie; like with sed -ie, instead of interpreting as another option, it will use e as an argument to -i, and use it as a suffix to backup the original file. See perldoc perlrun for more details there.

Perl's regex parsing is a little different from sed (better, imo) for more complicated things: generally speaking, use less backslashes.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜