我开始使用 sed 来替换文件中的文本,以便更轻松地批量更改文件的内容,并且我将每个值都需要设置为带有 BASH 的变量,并将替换为调用所有变量的函数替换现有文本。例子~
sed -i -e "s/$answer/$FORME $answer/g" ~$answer.txt
Run Code Online (Sandbox Code Playgroud)
$answer 是终端中命令的变量输入。$FORME 是根据 $answer 的输入定义的变量,但是 $FORME 包含“/”,我一直在网上浏览,找不到使用包含特殊字符的变量替换的方法。当我尝试在 $answer 上使用创建带有特殊字符的 $FORME 的命令时,会显示此错误:
sed: -e expression #1, char 15: unknown option to `s'
Run Code Online (Sandbox Code Playgroud)
我假设这意味着 $FORME 中的特殊字符被注册为实际命令的一部分,而不是要替换的字符串。请帮忙!
提前致谢!
您可以使用任何字符作为s
命令分隔符,例如,
sed -i -e "s|$answer|$FORME $answer|g" ~$answer.txt
Run Code Online (Sandbox Code Playgroud)
令人惊讶的是,这个问题在 Stack Exchange 上都有人提出和回答,但对于这个非常合理的问题,两个普遍有用的答案却是大海捞针。他们是:
1. 仅转义变量中 4 个可能的特殊字符
正如这里所指出的(尽管这个问题是 SE 厌恶一般问题的受害者),在 sed 命令的替换部分中只有 4 个字符被认为是特殊的s
:\
、&
、 换行符和分隔符(通常/
但实际上可以是任何东西)。
因此,要在 sed 中使用任意变量作为替换,请首先转义这四个字符的任何出现,如下所示:
REPL='Arbitrary variable potentially with special characters like / and & and \ and
newline\
newline2'
REPL=$(sed -e 's/[&\\/]/\\&/g; s/$/\\/' -e '$s/\\$//' <<<"$REPL")
hexdump -C <<< "$REPL"
Run Code Online (Sandbox Code Playgroud)
例如:
REPL='/&\
newline'
REPL=$(sed -e 's/[&\\/]/\\&/g; s/$/\\/' -e '$s/\\$//' <<<"$REPL")
sed "s/x/$REPL/" <<< "STARTxEND"
Run Code Online (Sandbox Code Playgroud)
产生:
START/&\
newlineEND
Run Code Online (Sandbox Code Playgroud)
正如预期的那样。
2. 使用等效工具逐字解释替换变量
perl
( ref ) 具有此功能,因为变量(只要通过导出变量或在调用行中设置它们而成为环境的一部分)是一等公民。\Q
替换字符串中不需要注释(但在正则表达式字符串中很有用)。
export REPL='/&\
newline'
perl -pe 's/x/$ENV{REPL}/' <<< "STARTxEND"
Run Code Online (Sandbox Code Playgroud)
产生:
START/&\
newlineEND
Run Code Online (Sandbox Code Playgroud)
awk
,尽管有ref,但没有。