【问题标题】:Globbing pattern: exclude a directory通配模式:排除目录
【发布时间】:2020-10-18 23:37:09
【问题描述】:

我有以下文件路径

/vol/form/various.txt
/vol/var/sender.py
/vol/var/hello.txt

我想获取所有包含form目录的.txt文件。例如,类似:

*.txt AND ! */form/*

这样做的正确通配模式是什么 - 即,在单一模式中(或者这不可能)?

【问题讨论】:

  • 结合globstarextglob,这个glob 可能会起作用:**/!(form)/*.txt——但我看到!(...) 不是很可靠;例如,如果form 的子目录中有文本文件,则不会被排除,**/!(form)/**/*.txt 匹配所有内容。但是如果.txt 文件总是直接在form 目录下,它应该可以工作。
  • 虽然是这样,但似乎太脆弱了

标签: regex shell unix find glob


【解决方案1】:

像这样:

find /vol ! -path '*/form/*' -type f -name '*.txt'

如果您需要否定模式,例如使用 regexfind -regex* 不支持 AFAIK 环顾。因此,仅使用一个 find 正则表达式是不可能的。

【讨论】:

  • @Giles -- 当然,是否可以仅使用一个 -path 参数来做到这一点?或者是否需要链接,这基本上是我的问题。
  • 您没有向我们展示您尝试过的内容,这是高质量问题所必需的。你测试过我的解决方案吗?这是一个完整的工作命令。不知道你还需要什么。这正是您提出问题的目的
  • @david542 -- 是的,我知道它有效,我只是想知道在单个模式字符串中执行更复杂模式的能力。
  • 这不是你原来的问题。不要更改 cmets 中的规则:如果这还不够,请打开一个新问题
【解决方案2】:

你可以否定一个 grep:

find /vol -type f -name '*.txt' | grep -v '/form/'

如果你想要一个单个正则表达式,你需要找到带有find 的文件名并提供给 GNU grep:

find /vol -type f | ggrep -oP "(?!.*?\/form\/)(^.*\.txt$)" 

或将Perl 与相同的正则表达式一起使用:

perl -MFile::Find -e 'find sub {
      print "$File::Find::name\n" if -f && m/(?!.*?\/form\/)(^.*\.txt$)/
      },"/vol/"'

正则表达式的解释:

(?!^.*?\/form\/)(^.*\.txt$)

^              ^                 Negative lookahead fail on /form/
                 ^       ^       Anchors for start and end of string
                   ^             all horizontal characters
                     ^^          literal . 
                                 (if not escaped it would match any character)
                       ^         txt extension 

Demo

【讨论】:

  • 是的,但不是像 OP 写的那样在 single expressionsingle parrern
  • 如果您可以在单个正则表达式中完成,请告诉我们 =)
  • 你去!可能但不优雅
  • 是的,重复使用不是很明显。 (^) 是什么?不明白
  • @不应该,扩展名是.py而不是.txt
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-06-10
  • 1970-01-01
  • 2018-12-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多