我正在得到一个
sed: -e expression #1, char 22: unterminated `s' command
我的脚本有问题吗? “老string”也有特殊的字符
#!bin/bash oldstring='<script>"[oldscript]"</script>' newstring='<script>"[newscript]"</script>' grep -rl $oldstring /path/to/folder | xargs sed -is/$oldstring/$newstring/g
正如@Didier所说的,你可以把你的分隔符改成除了/
之外的东西:
grep -rl $oldstring /path/to/folder | xargs sed -is@$oldstring@$newstring@g
grep -rl $oldstring . | xargs sed -i "s/$oldstring/$newstring/g"
当GNU的人们把递归的文件搜索引入grep时,他们真的搞砸了。 grep是用于在文件中找到RE并打印匹配的行(g / re / p记住?)不用于查找文件。 有一个非常好的工具,FINDing文件的名字非常明显。 无论发生在UNIX的口头禅上,做一件事,做得好吗?
无论如何,下面是你如何使用传统的UNIX方法来做你想做的事情(未经测试):
find /path/to/folder -type f -print | while IFS= read -r file do awk -v old="$oldstring" -v new="$newstring" ' BEGIN{ rlength = length(old) } rstart = index($0,old) { $0 = substr($0,rstart-1) new substr($0,rstart+rlength) } { print } ' "$file" > tmp && mv tmp "$file" done
不是通过使用awk / index()代替sed和grep,而是避免需要转义所有可能出现在您的旧字符串或新字符串中的RE元字符,并且找出一个字符作为您的sed分隔符, t出现在你的旧字符串或新字符串中,而且你不需要运行grep,因为替换只会出现在包含你想要的字符串的文件中。 说了这么一点,如果你不想修改文件的时候文件的时间戳发生改变,那么只要在执行mv之前在tmp和原始文件上做一个diff或者在AWK。
警告:以上不适用于包含换行符的文件名。 如果你有这些,那么让我们知道,我们可以告诉你如何处理它们。
sed
表达需要引用
sed -i "s/$oldstring/$newstring/g"
grep -rl SOSTITUTETHIS . | xargs sed -Ei 's/(.*)SOSTITUTETHIS(.*)/\1WITHTHIS\2/g'