2009-05-25 71 views
53

我需要做一个正则表达式查找和替换文件夹(及其子文件夹)中的所有文件。 linux shell命令会做什么?sed初学者:改变文件夹中的所有事件

例如,我想对所有文件运行此操作,并用新的替换文本覆盖旧文件。

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

http://theunixshell.blogspot.com/2012/12/find-and-replace-string-in-all-files.html – Vijay 2013-05-13 07:20:16

回答

82

没有办法,只用sed的做到这一点。你需要使用至少find工具一起:

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

此命令将创建一个.bak文件的每个改变的文件。

注:

  • -i论据sed命令是GNU扩展,因此,如果您正在使用的BSD的sed这个命令你将需要输出重定向到一个新的文件,然后重命名它。
  • find实用程序在旧的UNIX框中未实现-exec参数,因此,您需要改为使用| xargs
0

我可以建议(在备份文件):

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

为了便于携带,我不依赖于特定于linux或BSD的sed功能。相反,我使用Kernighan的overwrite脚本和派克关于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 "[email protected]" >$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 

因为shell截断文件之前sed可以读取它。

20

我更喜欢使用find | xargs cmd而不是find -exec,因为它更容易记住。

这个例子在全球取代“富”与.txt文件“栏”等于或低于当前目录:

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

-print0-0选项可以被排除在外,如果你的文件名不包含时髦人物如空间。

+1

如果你在OSX,尝试`找到。 -type f -name“* .txt”-print0 | xargs -0 sed -i''“s/foo/bar/g”`(注意为`-i`参数提供一个空字符串)。 – jkukul 2017-03-27 09:10:58

-4

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

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

这与问题无关。这个问题没有提到任何关于相同的文件/文件夹名称模式。请避免这样的答案 – 2017-10-16 10:12:52

相关问题