Bash中去除尾随转义换行符存变量:为何第二个sed命令生效?
Bash中去除字符串末尾转义换行符的问题解析
问题场景
我希望在Bash环境中去除字符串末尾的尾随转义换行符(\n)并将结果存储到变量中。
无法正常工作的命令
[xxx@ ~]$ var=`echo 'abc\ndef\n' | sed 's/\\n$//g'` [xxx@ ~]$ echo $var abc\ndef\n
可以正常运行的命令
[xxx@ ~]$ var=`echo 'abc\ndef\n' | sed 's/\\\\n$//g'` [xxx@ ~]$ echo $var abc\ndef
我原本以为sed命令被单引号包裹,仅需一个反斜杠转义即可,但实际并非如此,想知道第二个命令为何能正确执行。
原因解析
核心问题出在Bash的转义处理和sed的正则语法的两层转义逻辑上:
- Bash的单引号转义规则:单引号内的内容确实会被Bash原样传递,但这里的
\\会被Bash解析成单个\。比如你写sed 's/\\n$//g',Bash实际传给sed的命令是s/\n$//g。 - sed的正则匹配规则:在sed的正则里,
\n代表的是实际的换行符,而非字符串里的字面转义字符\n(也就是\+n这两个字符)。要匹配字面的\n,需要在sed里写成\\n——因为sed中单个\是用来转义特殊字符的,要表示字面的\,必须用两个\\,再加上n就是\\n。
把两层转义结合起来:要让sed最终拿到\\n,你需要在Bash单引号里写\\\\n——Bash会把每两个\转成一个,四个\就变成两个,加上n后正好是sed需要的\\n,这样才能精准匹配到字符串末尾的字面\n并删除。
内容的提问来源于stack exchange,提问作者toto imaima
相关产品推荐
相关产品推荐

