使用grep和sed递归查找和替换所有文件中的字符串

时间:2013-04-10 08:06:05

标签: linux bash recursion sed grep

我得到了

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

5 个答案:

答案 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'