为什么 grep 需要双反斜杠?

为什么 grep 需要双反斜杠?

我知道特殊字符会产生特殊动作:

$ echo 'abc[abc' | grep -o '['
grep: Invalid regular expression

请注意,单引号可以避免 shell 解释或源字符串更改出现问题。

我还知道需要反斜杠来转义这些特殊字符的特殊解释:

$ echo abc[abc | grep -o '\['
[

为了匹配 backslash-specialChar ( \[) grep 需要更多的反斜杠:

$ echo 'abc\[abc' | grep -o '\\\['
\[

但是像 an 这样的简单字符f并不特殊,匹配 a\f应该不需要额外的逃脱:

$ echo 'abc\fabc' | grep -o '\f'
f

但它确实:

$ echo 'abc\fabc' | grep -o '\\f'
\f

A文字字符串,如:

$ echo 'abc\fabc' | grep -F -o '\f'
\f

去证明\fgrep 以某种方式解释了 。

手动的状态:

'\' 字符后跟某些普通字符时,具有特殊含义:
/s
匹配空格,它是 '[[:space:]]' 的同义词。

暗示certain ordinary characters还有其他普通人物不在该列表中并且没有特别的地位。

因此,我的理解是 a \f(仅选择一个字符)应该匹配源字符串\f.

我缺少什么?

有关的:

1-grep:尾部反斜杠

2-grep 中转义斜杠“\”

3-为什么 sed 需要 3 个反斜杠来表示常规反斜杠?

答案1

但是像 f 这样的简单字符并不特殊,匹配 \f 不需要额外的转义:

$ echo 'abc\fabc' | grep -o '\f'
f

f并不特殊,但反斜杠在正则表达式中很特殊。常规字符前面的反斜杠的行为在实现反斜杠转义的不同实用程序中有所不同,但如下所示对于 POSIX 正则表达式,定义指出:

对前面带有未转义字符 ( '\' ) 的普通字符的解释是不明确的,但以下情况除外:[ (){}19括号内的表达式中的任意一个 ]

类似地,在扩展正则表达式中:

普通字符是受支持的字符集中的任何字符,除了 ERE 特殊字符中列出的 ERE 特殊字符。前面带有未转义 ( ) 的普通字符的解释\\是未定义的,除非在括号表达式的上下文中(请参阅 ERE 括号表达式)。

grep(或者更确切地说,它使用的正则表达式实现)只是选择解释\f为与f.人们可能会认为反斜杠删除了 the 的任何特殊属性f(即使它没有任何特殊属性),这与反斜杠在 ERE 中的工作方式一致。或者作为任意决定。


Linux 手册页regex(7)明确解释:

原子是[除其他外] a\后跟任何其他字符(!)(匹配该字符作为普通字符,就好像\不存在一样(!))

在我的 Mac 上,它grep代表\f换页符,就像 C 风格的转义符一样。所以printf '\f' | grep '\f'匹配,他们都将其解释为换页(printf被定义为这样做)。

答案2

我缺少什么?

就 grep 字符串而言,因为f它是正则表达式中的普通字符,'\f'所以与以下内容相同'f'

$ echo 'abc\fabc' 
abc\fabc
$ echo 'abc\fabc' | grep -o '\f'
f
$ echo 'abc\fabc' | grep -o 'f'
f

但是像 f 这样的简单字符并不特殊,不需要转义:

$ echo 'abc\fabc' | grep -o '\f'

f

但它确实:

$ echo 'abc\fabc' | grep -o '\\f'

\f

不,事实并非如此。回顾一下我之前的例子:

$ echo 'abc\fabc' | grep -o 'f'
f

的手册页re_format(7)记录 regexp\f等同于 regexp f

... '\' 后跟任何其他字符(与视为普通字符的字符匹配,就好像 '\' 不存在一样) ...

相关内容