递归替换文件中很长的字符串

递归替换文件中很长的字符串

我在许多文件中有一个非常长且复杂的字符串,我想递归地删除/替换它。该字符串包含许多斜杠、反斜杠和空格以及任何类型的特殊符号。我怎么做?简单的 find + sed 组合不起作用,因为其中的所有特殊符号我几乎无法逃脱。

是否可以将搜索字符串写入文件并将其用作搜索和替换命令的输入?

答案1

我假设该字符串可以包含除换行符和空字节之外的任何字符。您可以引用该字符串以用作 sed 模式。这些字符$*./[\^前面需要有一个反斜杠。在替换文本中,您需要引用字符\&/

regexp=$(printf %s "$old" | sed 's:[$*./\[^]:\\&:g')
replacement=$(printf %s "$new" | sed 's:[\&/]:\\&:g')
sed -e "s/$regexp/$replacement/g"

如果您有 Perl,那就更简单了。

export old new
perl -pe 's/\Q$ENV{old}/$ENV{new}/'

递归地作用于当前目录及其子目录中的所有文件:

regexp=$(printf %s "$old" | sed 's:[$*./\[^]:\\&:g')
replacement=$(printf %s "$new" | sed 's:[\&/]:\\&:g')
export regexp replacement
find . -type f -exec sh -c 'for x; do sed -e "s/$regexp/$replacement/g" <"$x" >"$x.new" && mv "$x.new" "$x"; done' _ {} +

或者

export old new
find . -type f -exec perl -i -pe 's/\Q$ENV{old}/$ENV{new}/' {} +

答案2

是的,您应该能够使用该-f选项来指定包含[列表]表达式的文件

   -f script-file, --file=script-file

          add the contents of script-file to the commands to be executed

然而,您仍然需要转义任何特殊字符(据我所知,没有与 grep 等效的 sed --fixed-strings) - 如果您的系统上有 perl,您可能希望考虑使用它,并使用\Q...\E带引号的字符串修饰符。

相关内容