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-H
、1-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 ":"
我今天在通配时 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-H
、1-2
和 ,
;它等同于:
GM12878_Hs_InSitu_MboI_r[EFGH12,]_*
正如我希望您现在看到的那样,它不会匹配任何两个字符条目(无下划线的版本会匹配)。
*
与正则表达式中的 *
不同。在正则表达式中 *
表示“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 ":"