我在许多文件中有一个非常长且复杂的字符串,我想递归地删除/替换它。该字符串包含许多斜杠、反斜杠和空格以及任何类型的特殊符号。我怎么做?简单的 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
带引号的字符串修饰符。