我得到了
sed: -e expression #1, char 22: unterminated `s' command
我的脚本有问题吗? “oldstring”也有特殊字符
#!bin/bash
oldstring='<script>"[oldscript]"</script>'
newstring='<script>"[newscript]"</script>'
grep -rl $oldstring /path/to/folder | xargs sed -i s/$oldstring/$newstring/g
答案 0 :(得分:42)
正如@Didier所说,您可以将分隔符更改为/
以外的其他内容:
grep -rl $oldstring /path/to/folder | xargs sed -i s@$oldstring@$newstring@g
答案 1 :(得分:13)
grep -rl $oldstring . | xargs sed -i "s/$oldstring/$newstring/g"
答案 2 :(得分:5)
当他们将递归文件搜索引入grep时,GNU的人真的搞砸了。 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分隔符的字符不能出现在旧字符串或新字符串中,并且您不需要运行grep,因为替换只会发生在包含所需字符串的文件中。说完所有这些,如果你不想在不修改文件的情况下改变文件时间戳,那么只需在执行mv之前在tmp和原始文件上执行diff,或者在执行之前执行fgrep -q AWK。
警告:上述内容不适用于包含换行符的文件名。如果你有那些,请告诉我们,我们可以告诉你如何处理它们。
答案 3 :(得分:3)
sed
表达式
sed -i "s/$oldstring/$newstring/g"
答案 4 :(得分:-1)
grep -rl SOSTITUTETHIS . | xargs sed -Ei 's/(.*)SOSTITUTETHIS(.*)/\1WITHTHIS\2/g'