A

A

我的问题来源是答案在此链接上,加上一些额外的东西

更新

我理解第一个命令 iegrep \\[[a-z\|1-9]*\\] file但我不理解第二个命令 ie 的输出grep \[[a-z\|1-9]*\] file

现在,我只想了解第二个命令的输出是如何构造的,特别是为什么 grep 完全选择了整个第三行和第四行,但只选择了第二行和第三行直到第一行]

在此输入图像描述

答案1

这里有太多变量和未声明的假设,无法详尽地回答您的问题。

这里的主要陷阱是 shell(即大多数 Bourne 兼容的 shell - 实际上不确定 zsh 或 csh 及其衍生物)默认将通过未扩展的 glob如果它不匹配任何东西。因此,首先尝试使用像这样的表达式\\[[a-z0-9]*\\]作为通配符。如果没有匹配的文件(比如\fno[rd\]非字母都是文字的)通配符将grep逐字传递。

(让我们再次检查一下。这是一个双反斜杠,即带引号的文字反斜杠后跟两个左方括号。第一个创建一个字符类,其第一个字符是第二个,文字[。将其解析为正则表达式的结果有所不同,但同样令人费解。)

对此唯一明智的解决方案是正确引用任何不需要通过 shell 进行空格标记化和通配符扩展的内容。我的建议是在所有正则表达式周围使用单引号。然后,您将能够对匹配内容和方式形成合理的期望,而无需对您的模式的专家解释(一个 shell,一个正则表达式)。

如果你想var[1]完全匹配,正则表达式[a-z]*\[[0-9]*\]可以做类似的事情。如果您希望方括号成为字符类的一部分,请尝试[][a-z0-9]*其中第一个]和第二个[是字符类的文字成员。如果您将它们传递到grepshell 中,请记住它们周围的单引号。

答案2

我们慢慢走吧。如果有一个包含以下内容的文件(仅一行,以便更容易显示):

$ cat infile
list[1]; i[ab1]; var[1] [1]var  [1]var[2]

A

简单的grep --color a会将所有 a 显示为红色。 (因为该网站确实允许控制颜色:假设粗体是红色):

$ grep --color a infile  

list[1]; i[Ab1]; vAr[1] [1]vAr [1]vAr[2]

如果 a 不带引号(如上所述)或带引号,则会发生完全相同的情况:

$ grep --color \a infile  

list[1]; i[Ab1]; vAr[1] [1]vAr [1]vAr[2]

$ grep --color "a" infile  

list[1]; i[Ab1]; vAr[1] [1]vAr [1]vAr[2]

$ grep --color 'a' infile  

list[1]; i[Ab1]; vAr[1] [1]vAr [1]vAr[2]

为什么?因为 a 是两个都

  1. 对外壳来说并不特殊。
  2. shell 删除引号,并且 grep 接收a与第一个参数相同的内容。反斜杠引号、双引号或单引号。

]

如果我们想选择大括号](让我们从右大括号开始):

$ grep --color ] infile  

list[1]; i[ab1]; var[1][1]var [1]var[2]

]如果引用(任何引用)也会发生同样的情况。
在这种情况下,它]对于 shell 来说是特殊的,但在没有匹配的左大括号的情况下则不然。

对于右大括号,事情变得更加复杂。所有这些都会引发错误:

grep --color  [  infile
grep --color '[' infile
grep --color "[" infile

为什么?因为 grep 接收到的内容全部案件是单一的[
您可以通过这个简单的 echo 来了解 shell 的作用:

 $ echo \[ "[" '['
 [ [ [

shell 删除一级引用,所有值看起来都一样。

[

但是 grep 想要接收到的理解我们实际上正在搜索的字符[是反斜杠引用的方括号 ( \[)。这一切都会发生:

$ echo \\[ "\[" '\['
\[ \[ \[

grep 可以与其中任何一个一起使用:

$ grep --color \\[ infile

list[1]; i[ab1]; var[1][1]var[1]var[2]

[[]

使用[[](只有一个字符的字符列表)将得到相同的结果(只要它被引用)。

$ grep --color '[[]' infile

list[1]; i[ab1]; var[1][1]var[1]var[2]

Grep 需要准确接收[[]才能正常工作。看起来似乎不需要引号:

$ echo \[\[\] "[[]" '[[]' [[]
[[] [[] [[] [[]

但如果你创建一个名为 的文件[,这个想法就会被打破:

$ touch \[
$ echo \[\[\] "[[]" '[[]' [[]
[[] [[] [[] [

那是因为它[对于 shell 来说是特殊的。对于 shell,它启动文件名通配模式。如果一个(或多个)文件与该模式匹配,则文件列表将被替换。

所以,这将正确工作:

$  grep --color '[[]' infile

list[1]; i[ab1]; var[1][1]var[1]var[2]

而这个:grep --color '[]]' infile将匹配右大括号。

[][]

匹配左方括号在右方括号中,您需要特定的字符序列(当然,带引号)。

如果你尝试这样做:

$  grep --color '[[]]' infile

不会有比赛,根本没有。你需要这个才能让它正常工作:

$ grep --color '[][]' infile

list[1]; i[ab1]; var[1][1]var[1]var[2]

按照该特定顺序,右大括号必须是字符范围内的第一个字符。左大括号必须是字符列表中的最后一个字符。

[]a-z0-9[]

然后,您可以添加其他字符(但不能添加;):

$ grep --color '[]a-z0-9[]' infile

列表[1];我[ab1];变量[1][1]变量[1]变量[2]

然后,您可以添加|范围中缺少的内容并进行您发布的链接的匹配。该链接中的正则表达式与此处不同,并且以非常不同的方式工作。它以匹配一个[、其他一些字符开始,并以结束符结束]。类似的东西(贪婪的本质*占据了整条线):

$  grep --color '\[.*\]' infile

list[1];我[ab1];变量[1] [1]变量[1]变量[2]

或者也类似这样:

$ grep --color '[[][a-c0-9]*[]]' infile

list[1]; i[ab1]; var[1][1]var[1]var[2]`

相关内容