Unix Shell循环遍历文件并替换文本

3

我对这方面还比较新,需要一个shell文件来循环处理文件夹中的所有“.xml”文件,并进行一些文本替换。

到目前为止,我想出了以下方法:

sed "s/old_text/new_text/g" testfile.xml -i

然而,我希望这能在当前文件夹中运行所有的xml文件,而不仅仅是“testfile.xml”。此外,我该如何备份原始文件?

欢迎提供任何意见!非常感谢!

3个回答

9

要在所有的xml文件上运行sed,只需指定通配符即可。

sed "s/old_text/new_text/g" *.xml -i

要创建备份,只需在-i后指定扩展名:

sed "s/old_text/new_text/g" *.xml -i~

请注意,通常最好使用支持XML的工具来处理XML。

1
...然后祈祷old_textnew_text都不包含任何$, /, \1, &, ?, *, (, ), [, ], \+, ., etc等字符。请注意,sed不是操作字符串,而是操作具有受限字符集的正则表达式。请参考https://dev59.com/ul0b5IYBdhLWcg3wGN0s#29626460,并考虑使用一个可以操作字符串的工具,例如awk。您可以通过在命令周围使用单引号而不是双引号来稍微降低出错的风险。 - Ed Morton
如果您使用XML库,它就可以实现。请参阅https://www.gnu.org/software/gawk/manual/html_node/gawkextlib.html。但主要是我想提醒自称为新手的人,他将无法在sed中使用字符串。 - Ed Morton
@EdMorton:有趣的是,我不知道它们的存在。你能提供链接吗? - choroba
刚刚更新了我的先前评论,加入了一个链接。另请参阅http://sourceforge.net/projects/gawkextlib/。 - Ed Morton
我需要进行大约150个替换操作,其中包括“&”、“#”、“;”等字符。我尝试使用批处理文件进行操作,但是没有找到一个易于使用的解决方案。我正在使用sed命令,因为这是我在谷歌搜索中找到的,但如果您有更安全(且简单)的想法,我将非常高兴去研究它。请指点我一下 :) - horace_vr
显示剩余2条评论

3

针对当前目录下所有的.xml文件:

sed -i.bak 's/old_text/new_text/g' *.xml

为了进入子目录,请与find结合使用:
find . -name '*.xml' -exec sed -i.bak 's/old_text/new_text/g' '{}' \;

备份文件将以.xml.bak的方式结束(-i参数将附加到原始文件名后面)。

应该指出,这将创建所有 .xml 文件的 .bak 版本,而不仅仅是更新的文件。 - hshah
如果我不想要备份文件怎么办? - tryingToBeBetter

2

一个实用的Shell脚本,如果你想要使用多种方法来清理一堆文件 - 这些方法在单行命令中会变得有点不切实际...

# only take files form certain subfolders and certain extensions

# be careful to not tamper with .git or .svn folders 
# - thus excluding all hidden folders as an extra precaution
# - also tampering with node_modules is a bad idea

FILES=$(find . -type f -regextype posix-extended     \
    -regex "^\./(public|source)/.*\.(scss|js)$"         \
    -not -regex ".*\/(\.|node_modules).*")

for f in $FILES
do
echo "Processing $f file..."

# all files: prune trailing whitespace on each file.
sed -i 's/ *$//' $f

if [[ $f =~ \.js$ ]]; then
    echo "javascript file!"
    # DO stuff
fi

if [[ $f =~ \.scss$ ]]; then
    echo "scss file!"
    # \b whole word matching – stackoverflow.com/a/1032039/444255
    sed -i 's/\#000\b/black/g' $f
    sed -i 's/\#000000\b/black/g' $f
    sed -i 's/\#fff\b/white/g' $f
    sed -i 's/\#ffffff\b/white/g' $f
fi

done

注意:伴随着强大的能力而来的是巨大的责任,批量替换意味着拥有了强大的能力...


如果文件名包含空格,这个方法就无法正常工作。 - ddekany

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