这只是一个显示问题的测试文件。原来的部分看起来像这样:
arch systemd[908]:
Run Code Online (Sandbox Code Playgroud)
现在我可以用“:”字符替换右括号
krys@archeos:~/test]$ cat jctl.log | cut -d " " -f 4,5 | head | sed s/]/:/g
arch systemd[908::
Run Code Online (Sandbox Code Playgroud)
当我尝试更换开口支架时,它不起作用:
krys@archeos:~/test]$ cat jctl.log | cut -d " " -f 4,5 | head | sed s/[/:/g
sed: -e expression #1, char 7: unterminated `s' command
Run Code Online (Sandbox Code Playgroud)
然后我用 1 \ 字符转义了“[”,但它仍然不起作用
krys@archeos:~/test]$ cat jctl.log | cut -d " " -f 4,5 | head | sed s/[/:/g
sed: -e expression #1, char 7: unterminated `s' command
Run Code Online (Sandbox Code Playgroud)
使用 2 个“\”即可:
krys@archeos:~/test]$ cat jctl.log | cut -d " " -f 4,5 | head | sed s/\\[/:/g
arch systemd:908]:
Run Code Online (Sandbox Code Playgroud)
这是我的问题:
我只是想了解这一点。我现在知道如何做到这一点,但我对不知道细节感到不满意。
这是因为您没有引用 sed 表达式(坏主意,养成将sed
命令放在单引号中的习惯)。您需要转义的原因[
是因为[
它在正则表达式中具有特殊含义,它打开一个字符类(例如,[abc]
将匹配a
、b
或 之一c
)。您不需要转义,]
因为 sed 足够聪明,知道在这种情况下,]
不会关闭字符类,因为没有前面[
可以关闭。
现在,因为您没有引用 sed 表达式,这意味着 shell 将在将其传递给之前尝试解释它sed
。因此,shell 会看到您的\[
,并使用转义符将其未转义的传递给 sed。您可以通过以下方式查看此操作的实际效果set -x
:
$ set -x
$ sed s/\[/:/g jctl.log
+ sed 's/[/:/g' jctl.log
sed: -e expression #1, char 7: unterminated `s' command
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,实际运行的命令是sed 's/[/:/g' jctl.log
而不是sed 's/\[/:/g' jctl.log
:shell 已经消耗了转义符。然后会失败,因为 sed 正在寻找结束符]
,但没有找到,因此将整个字符串视为/:/g
字符类的内容,因此失败,因为它找不到命令的结尾s///
。
添加第二级转义允许 shell 消耗一级转义,然后仍然将转义传递给[
sed:
$ sed s/\\[/:/g jctl.log
+ sed 's/\[/:/g' jctl.log
arch systemd:908]:
Run Code Online (Sandbox Code Playgroud)
您可以在上面的输出中看到 sed 是\[
now 给出的,而不是[
。
如果您始终引用 sed 命令,所有这些问题都会消失:
$ sed 's/\[/:/g' jctl.log
arch systemd:908]:
Run Code Online (Sandbox Code Playgroud)