我有点困惑需要多少反斜杠才能|在 grep 的正则表达式中转义交替运算符。这个
echo abcdef | grep -e"def|zzz"
Run Code Online (Sandbox Code Playgroud)
不输出任何内容,因为 grep 不处于扩展正则表达式模式。用一个反斜杠转义,
echo abcdef | grep -e"def\|zzz"
Run Code Online (Sandbox Code Playgroud)
打印abcdef。更令人惊讶的是,用 2 个反斜杠转义也有效,
echo abcdef | grep -e"def\\|zzz"
Run Code Online (Sandbox Code Playgroud)
打印abcdef。用三个反斜杠转义失败,
echo abcdef | grep -e"def\\\|zzz"
Run Code Online (Sandbox Code Playgroud)
什么都不打印。
有没有人有解释,特别是对于 2-backslash case?
编辑:
使用这个简单的参数打印程序,
void main(int argc, char** argv)
{
for (int i = 0; i < argc; i++)
printf("Arg %d: %s\n", i, argv[i]);
}
Run Code Online (Sandbox Code Playgroud)
我调查了我的 shell 用上面的命令行做了什么:
-e"def|zzz" 变成 -edef|zzz
-e"def\|zzz" 变成 -edef\|zzz
-e"def\\|zzz" 变成 -edef\\|zzz
-e"def\\\|zzz" 变成 -edef\\\|zzz
所以所有的双引号都被删除了,反斜杠和管道不会被 shell 改变。我怀疑 grep 本身对文字 string 做了一些特别的事情\\|。
小写-e选项用于表示多个搜索操作。隐含的交替是:
$ echo abcdef | grep -e 'def' -e'zzz'
abcdef
$ echo abczzz | grep -e 'def' -e'zzz'
abczzz
Run Code Online (Sandbox Code Playgroud)
或者,您可以使用上面的-E选项来扩展正则表达式表示法:
$ echo abcdef | grep -E 'def|zzz'
abcdef
Run Code Online (Sandbox Code Playgroud)
我相信这可以直接解决您的问题(无论是用于-e交替还是-E用于扩展正则表达式表示法)。希望这可以帮助 :-)
FWIW,反斜杠的问题是它对|bash 有特殊含义,需要转义,除非它在单引号中。以下是有关引用和转义规则以及常见陷阱的资源: http: //wiki.bash-hackers.org/syntax/quoting
第一个失败,因为 grep 以编程方式转义管道,导致正则表达式中出现文字管道。
最后一次尝试失败,因为\\\|结果是在正则表达式中先出现文字反斜杠,然后出现文字管道。
echo 'def|zzz' | grep -e "def|zzz" --> def|zzz
echo 'def\\|zzz' | grep -e "def\\\|zzz" --> def\|zzz
Run Code Online (Sandbox Code Playgroud)