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

foo[E1,E2,...]* glob matches desired contents, but foo[E1,E2,...]_* does not?

我今天在通配时 Bash Shell 的行为中看到了一些奇怪的东西。

所以我 运行 一个带有以下 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。

你误解了你的 glob 在做什么。

您期待的是:

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

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

比较:

$ 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

你想要后者的扩展。

您的扩展使用 字符 class 匹配字符 E-H1-2,;它等同于:

GM12878_Hs_InSitu_MboI_r[EFGH12,]_*

正如我希望您现在看到的那样,它不会匹配任何两个字符条目(无下划线的版本会匹配)。

文件系统 glob 中的

* 与正则表达式中的 * 不同。在正则表达式中 * 表示“0 个或多个前面的模式”,但在文件系统 glob 中它表示 "anything at all of any size"。因此,在您的第一个示例中,_ 只是 * 中 "anything" 的一部分,但在第二个示例中,您匹配字符 class 中的任何单个字符(不是您似乎试图定义的模式)然后是 _ 然后是任何东西。

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

要获得您想要的模式分组,您应该使用 { 而不是像

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

据我所知,this article 支持我,方括号不是作为一个选择,而是作为一个字符集,所以使用 [E1,E2,F,G1,G2,H] 实际上等同于恰好一个[EGHF12,] 的出现。然后,您可以将第二个结果解释为 "one character of EGHF12, and an underscore",它匹配 GM12878_Hs_InSitu_MboI_rF_TagDirectory: 但不匹配 GM12878_Hs_InSitu_MboI_rG1_TagDirectory:r 后跟更多 "one occurrence of...")。

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

遗漏的内容

正确的表达方式是:

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