sed beginner:更改文件夹中的所有实例

时间:2009-05-25 02:42:58

标签: regex linux shell sed

我需要对文件夹(及其子文件夹)中的所有文件进行正则表达式查找和替换。 linux shell命令会做什么?

例如,我想在所有文件上运行它,并使用新的替换文本覆盖旧文件。

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

9 个答案:

答案 0 :(得分:108)

仅使用sed无法做到这一点。您至少需要使用find实用程序:

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

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

注意:

  • -i命令的sed参数是GNU扩展名,因此,如果您使用BSD的sed运行此命令,则需要将输出重定向到新文件,然后重命名。
  • find实用程序未在旧UNIX框中实现-exec参数,因此,您需要使用| xargs代替。

答案 1 :(得分:35)

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

此示例全局替换" foo"用" bar"在当前目录或以下的.txt文件中:

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

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

答案 2 :(得分:6)

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

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

答案 3 :(得分:1)

我建议(备份文件后):

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

答案 4 :(得分:1)

for i in $(ls);do sed -i 's/old_text/new_text/g' $i;done 

答案 5 :(得分:0)

示例:将/ app / config /文件夹及其子文件夹下的所有ini文件的{AutoStart}替换为1:

sed 's/{AutoStart}/1/g' /app/config/**/*.ini

答案 6 :(得分:0)

这对我有用(在Mac终端上,在Linux上您不需要'' -e):

sed -i '' -e 's/old text/new text/g' `grep 'old text' -rl *`

命令grep 'old text' -rl *列出存在“旧文本”的工作目录(和子目录)中的所有文件。然后将其传递给sed。

答案 7 :(得分:-3)

可能想尝试my mass search/replace Perl script。与链式效用解决方案相比具有一些优势(比如不必处理多级shell元字符解释)。

答案 8 :(得分:-3)

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

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