【问题标题】:How can I match this pattern of file name in a directory, and output the matched?如何匹配目录中的这种文件名模式,并输出匹配的?
【发布时间】:2016-05-25 08:28:17
【问题描述】:

这个目录下有很多文件:

[ichen@ui01 data]$ ls
data.list
data.root
ntuple.data15_13TeV.00276262.DAOD_FTAG2.root
ntuple.data15_13TeV.00276329.DAOD_FTAG2.root
ntuple.data15_13TeV.00276336.DAOD_FTAG2.root
ntuple.data15_13TeV.00276416.DAOD_FTAG2.root
ntuple.data15_13TeV.00276511.DAOD_FTAG2.root

我想创建一个列表,其中仅包含具有以下模式的文件:

    [many chars].[many chars].[many numbers].[many chars].root

匹配文件名,例如:

ntuple.data15_13TeV.00276262.DAOD_FTAG1.root
ntuple.data15_13TeV.00276329.DAOD_FTAG2.root
ntuple.data15_13TeV.00276336.DAOD_FTAG3.root
etc...

如何使用正则表达式来实现这个目标? 也许我们可以使用这种语法:

for f in `ls`;do if [....];then echo $f;fi;done  > log.list

【问题讨论】:

  • pattern like -> 完全一样?你到底是什么意思?你能用文字描述应该是什么格式或提供多个匹配文件名的例子吗?
  • @Dropout 嗨,我编辑了我的问题以满足您的要求。

标签: regex linux shell


【解决方案1】:

在正则表达式领域,许多道路通向罗马。 :)

ls | egrep '^\w*\.\w*\.[0-9]*\.\w*\.root$'

^ 标记一行的开始 $ 标记一行的结尾 \w 是一个单词字符 \w* 是许多工作字符 .是一个字面的 '.'字符,一个不加掩码的“。”在正则表达式中代表“任何字符” [0-9] 是 0 到 9 之间的任意数字

对于你的具体例子:

for f in `ls`;do echo $f | egrep '^\w*\.\w*\.[0-9]*\.\w*\.root$';done

现在包括 if 语句:

for f in `ls`; do if [[ $f =~ '\w*\.\w*\.[0-9]*\.\w*\.root' ]]; then echo $f; fi; done

在这种情况下,我必须删除行开头和结尾 (^...$) 以使其匹配。不知道为什么。一般来说,=~ 会检查正则表达式。

【讨论】:

  • 比你。但是我如何使用这种语法 :for f in ls;do if [....];then echo $f;fi;done > log.list ?只是为了好奇。
  • 添加了一个 for 循环...但还不是很清楚,您要保留语法的哪一部分。
  • 如果我想使用“if”,我该如何实现呢?
  • 我要保留的语法是“if”结构。
  • 你好,我试过你的方法:for f in `ls`; do if [[ $f =~ '\w*\.\w*\.[0-9]*\.\w*\.root' ]]; then echo $f; fi; done 但是好像不行,没有回显。也许有问题?
【解决方案2】:
ls | grep '..*[.]..*[.][0-9][0-9]*[.]..*[.]root > log.list 

应该做的工作

【讨论】:

  • . outside [] 匹配任何字符一次,.* outside [] 匹配零个或多个字符,[.] 匹配一个点
  • 谢谢!但是我怎样才能使用这样的语法:for f in ls;do if [....];then echo $f;fi;done > log.list。我知道你的方法会奏效,但我还是很好奇。
  • 没有看到任何原因,但是如果... for f in $( ls ) ; do echo "$f" |grep -q <expr from above>; test $? -eq 0 && echo $f; done ?如果需要,您可以用 if 替换 test ... 的东西。
  • 您也可以尝试摆弄 shell 正则表达式本身,但我无法从我的脑海中确切说出如何,我总是在尝试test [[ $f =~ <...> ]] && echo "$f" 将与您可以在 ls 上使用的模式相同只列出想要的文件。,如果需要的话,你可以用一个替换 test ... 的东西。
  • 感谢您的帮助,我找到了方法!双方括号内的 ' ' 是不允许的。我用这个方法成功了:for f in `ls`;如果 [[ $f =~ ..*\...*\.[0-9]*\...*\.root ]];然后回显 $f;菲;完成
【解决方案3】:

不必那么复杂。您只需要列出与特定模式匹配的文件 - 通配符基本上就足够了,不需要正则表达式。

ls -1 ntuple.data*.*.*.root > log.list

【讨论】:

  • 谢谢,但出于好奇,我想知道正则表达式的用法和语法,例如:for f in 'ls';做 if [...];then echo $f;菲;完毕。这可以用于一些复杂的情况。
猜你喜欢
  • 2021-09-17
  • 2015-11-01
  • 2014-05-02
  • 1970-01-01
  • 2013-01-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-07
相关资源
最近更新 更多