在文件中查找和替换字符串

16

我正在尝试在一个文件夹中的文件中查找和替换字符串。

有人可以帮帮我吗?

我的脚本如下:

#!/bin/bash
OLD="This is a"
NEW="I am a"
DPATH="/home/user/test/*.txt"
BPATH="/home/user/test/backup/foo"
[ ! -d $BPATH ] && mkdir -p $BPATH || :
for f in $DPATH
do
  if [ -f $f -a -r $f ]; then
    /bin/cp -f $f $BPATH
    sed "s/$OLD/$NEW/g" "$f"
   else
    echo "Error: Cannot read $f"
  fi
done

现在似乎找到了字符串'This is a'并将其替换为'I am a',但这只会在屏幕上打印出来。

我需要它在文件中进行替换。

谢谢

4个回答

33

使用 sed-i 选项来直接进行修改:

sed -i "s/$OLD/$NEW/g" "$f"
    ^^

工作得很好!我知道我漏掉了什么。谢谢。 - terrid25
好的,有没有一种简单的方法可以修改我的shell脚本,以便它可以检查子文件夹?/home/user/test/xyz? - terrid25
#!bin/bash OLD="这是一个" NEW="我是一个" BPATH="/home/user/backup/foo" find . -name '*.shtml' -type f | while read filename do /bin/cp -f $filename $BPATH sed -i "s/$OLD/$NEW/g" $filename done - terrid25
当我尝试使用-i时,我收到了以下错误:sed: illegal option -- i Usage: sed [-n] [-e script] [-f source_file] [file...] - Dchris
1
@Dchris -i选项并不是完全可移植的,虽然在大多数平台上都以某种形式支持。在*BSD(包括MacOS)上,您需要使用-i'';如果您根本没有sed -i,可以尝试使用perl -pi -e,其中一个简单的sed脚本可以直接在Perl中使用,但请注意正则表达式方言的差异(您主要需要了解如何在某些地方添加或删除反斜杠)。 - tripleee

2

输出结果会显示在屏幕上 (stdout),原因如下:

sed "s/$OLD/$NEW/g" "$f"

尝试将重定向结果写入文件(以下示例会将结果重定向到一个新文件并将其重命名来覆盖原始文件):

sed "s/$OLD/$NEW/g" "$f" > "$f.new" && mv "$f.new" "$f"

这会创建一个 .text.new 文件,原始文件 example.txt 被覆盖并变为空白。有什么想法为什么会这样? - terrid25
可能是因为aix没有引用变量"$f.new"(两个地方)和"$f"。此外,mv不应该是无条件的。相反,它应该是sed ... && mv ... - Dennis Williamson
好的,我现在已经将$OLD更改为URL,并返回错误:sed:无法打开文件ww.google.co.uk//g:没有那个文件或目录。 'sed'命令似乎不喜欢URL中的//部分。有没有办法克服这个问题? - terrid25
1
@user390426:在 sed 命令中更改分隔符:“s|$OLD|$NEW|g”。 - Dennis Williamson

0
这是我使用的片段,它会删除当前目录下所有文件中APA和BEPA之间的所有内容(包括跨多行,并且还会删除APA和BEPA本身),但不包括.svn目录。
find . \! -path '*.svn*' -type f -exec sed -i -n '1h;1!H;${;g;s/APA[ \t\r\n]*BEPA//g;p}' {} \;

0

看看这个

http://cs.boisestate.edu/~amit/teaching/handouts/cs-unix/node130.html

##########################################################
\#!/bin/sh

\# sed/changeword

prog=`basename $0`

case $# in
0|1) echo 'Usage:' $prog '<old string> <new string>'; exit 1;;
esac

old=$1
new=$2
for f in *
do
        if test "$f" != "$prog"

        then
            if test -f "$f"
            then
                sed "s/$old/$new/g" $f > $f.new
                mv $f $f.orig
                mv $f.new $f
                echo $f done
            fi
        fi
done

##############################################################

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接