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