foo [E1,E2,...] * glob匹配所需的内容,但foo [E1,E2,...] _ *不匹配?

时间:2015-05-18 15:01:56

标签: regex linux bash shell glob

我在今天看到了Bash Shell在globbing时的行为很奇怪。

所以我运行了一个带有以下Glob的ls命令:

ls GM12878_Hs_InSitu_MboI_r[E1,E2,F,G1,G2,H]* | grep ":"

结果如预期

GM12878_Hs_InSitu_MboI_rE1_TagDirectory:
GM12878_Hs_InSitu_MboI_rE2_TagDirectory:
GM12878_Hs_InSitu_MboI_rF_TagDirectory:
GM12878_Hs_InSitu_MboI_rG1_TagDirectory:
GM12878_Hs_InSitu_MboI_rG2_TagDirectory:
GM12878_Hs_InSitu_MboI_rH_TagDirectory:

然而,当我通过在此

中引入下划线来更改相同的正则表达式时
ls GM12878_Hs_InSitu_MboI_r[E1,E2,F,G1,G2,H]_* | grep ":"

我的预期结果是如上所示的完整集合,但我得到的是一个子集:

GM12878_Hs_InSitu_MboI_rF_TagDirectory:
GM12878_Hs_InSitu_MboI_rH_TagDirectory:

当我在星号之前引入下划线符号时,有人可以解释我逻辑中的错误吗?

我正在使用Bash。

3 个答案:

答案 0 :(得分:4)

你误解了你的小伙子正在做什么。

你期待这个:

GM12878_Hs_InSitu_MboI_r[E1,E2,F,G1,G2,H]*

是一个包含任何逗号分隔段的文件,但不是[] globbing所做的。 [] globbing是一个字符类扩展。

比较

$ echo GM12878_Hs_InSitu_MboI_r[E1,E2,F,G1,G2,H]
GM12878_Hs_InSitu_MboI_r[E1,E2,F,G1,G2,H]

你想要得到的东西(括号{}扩展):

$ echo GM12878_Hs_InSitu_MboI_r{E1,E2,F,G1,G2,H}
GM12878_Hs_InSitu_MboI_rE1 GM12878_Hs_InSitu_MboI_rE2 GM12878_Hs_InSitu_MboI_rF GM12878_Hs_InSitu_MboI_rG1 GM12878_Hs_InSitu_MboI_rG2 GM12878_Hs_InSitu_MboI_rH

你想要后一种扩张。

您的扩展使用的字符类与字符E-H1-2,匹配;它与:

完全相同
GM12878_Hs_InSitu_MboI_r[EFGH12,]_*

正如我所期望的那样,你现在可以看到,它不会匹配任何两个字符条目(无下划线版本的情况)。

答案 1 :(得分:0)

文件系统globs中的

*与正则表达式中的*不同。在正则表达式中*表示&#34; 0或更多的前一个模式,&#34;但是在文件系统中它意味着任何大小的任何东西&#34;。所以在你的第一个例子中,_只是&#34;任何事物的一部分&#34;来自*,但在第二个中你匹配角色类中的任何一个角色(不是你想要定义的模式),然后是_,后面跟着任何东西。< / p>

此外,角色课程不会像您尝试使用它们那样工作。 [...]将匹配括号内的任何字符,因此您的模式实际上与[EFGH12,]相同,因为这些是您定义的类中的所有字母。

要获得所需的模式分组,您应该使用{代替[

ls GM12878_Hs_InSitu_MboI_r{E1,E2,F,G1,G2,H}_* | grep ":"

答案 2 :(得分:-1)

据我所知,this article支持我,方括号不作为选择而是作为字符集,所以使用[E1,E2,F,G1,G2,H]实际上只相当于一个发生[EGHF12,]。然后,您可以将第二个结果解释为&#34; EGHF12,的一个字符和一个下划线&#34;,它与GM12878_Hs_InSitu_MboI_rF_TagDirectory:匹配但不匹配GM12878_Hs_InSitu_MboI_rG1_TagDirectory:(有r接着是更多的&#34;一次......&#34;)。

第一个正则表达式有效,因为您使用了星号,它与错误的[...]错过了匹配的星号。

正确的表达方式是:

ls GM12878_Hs_InSitu_MboI_r{E1|E2|F|G1|G2|H}* | grep ":"