sed初学者:改变文件夹中的所有事件

我需要做一个正则expression式查找并replace文件夹(及其子文件夹)中的所有文件。 什么是Linux shell命令来做到这一点?

例如,我想在所有文件上运行这个文件,并用新的replace文本覆盖旧文件。

sed 's/old text/new text/g' 

没有办法只用sed来做。 您至less需要使用find实用程序:

 find . -type f -exec sed -i.bak "s/foo/bar/g" {} \; 

此命令将为每个更改的文件创build一个.bak文件。

笔记:

  • sed命令的-i参数是一个GNU扩展,所以,如果你正在用BSD的sed运行这个命令,你需要将输出redirect到一个新的文件,然后重命名它。
  • find实用程序不在旧的UNIX框中实现-exec参数,因此,您将需要使用| xargs | xargs代替。

我更喜欢用find | xargs cmd find | xargs cmd find -exec因为它更容易记住。

此示例全局replace当前目录下或以下的.txt文件中的“foo”。

 find . -type f -name "*.txt" -print0 | xargs -0 sed -i "s/foo/bar/g" 

如果您的文件名不包含诸如空格之类的时髦字符,则可以省略-print0-0选项。

为了便于携带,我不依赖于特定于linux或BSD的sed特性。 相反,我使用了Kernighan和Pike在Unix编程环境下的书。

那么命令是

 find /the/folder -type f -exec overwrite '{}' sed 's/old/new/g' {} ';' 

overwrite脚本(我使用的地方)是

 #!/bin/sh # overwrite: copy standard input to output after EOF # (final version) # set -x case $# in 0|1) echo 'Usage: overwrite file cmd [args]' 1>&2; exit 2 esac file=$1; shift new=/tmp/$$.new; old=/tmp/$$.old trap 'rm -f $new; exit 1' 1 2 15 # clean up files if "$@" >$new # collect input then cp $file $old # save original file trap 'trap "" 1 2 15; cp $old $file # ignore signals rm -f $new $old; exit 1' 1 2 15 # during restore cp $new $file else echo "overwrite: $1 failed, $file unchanged" 1>&2 exit 1 fi rm -f $new $old 

这个想法是,只有在命令成功的情况下才会覆盖文件。 有用的find ,也是你不想使用的地方

 sed 's/old/new/g' file > file # THIS CODE DOES NOT WORK 

因为在sed可以读取之前,shell会截断该文件。

我可以build议(备份你的文件后):

 find /the/folder -type f -exec sed -ibak 's/old/new/g' {} ';' 

可能要尝试我的大众search/replacePerl脚本 。 与chained-utility解决scheme相比有一些优点(比如不需要处理多层次的shell元字符解释)。

如果文件夹中的文件的名称有一些常规名称(如file1,file2 …),我已经用于循环。

 for i in {1..10000..100}; do sed 'old\new\g' 'file'$i.xml > 'cfile'$i.xml; done