Regex 使用Linux Shell正则表达式匹配文件名

Regex 使用Linux Shell正则表达式匹配文件名,regex,linux,shell,find,perl,bash,Regex,Linux,Shell,Find,Perl,Bash,我需要一种方法来匹配目录中的文件名 例如,我有三个文件: CAt_DoG_ZebRa.TXT MOUSE_lion_deer_BIRD.TXT fIsh_biRD_LION.TXT 我无论如何都不是正则表达式专家,但是我以前在SnapLogic和Pentaho中使用过类似的东西: (?i).*(?=.*bird)(?=.*lion).*.TXT 上述内容将匹配所有包含单词“bird”和“lion”的文件名,忽略大小写,单词的顺序无关紧要。非常强大!因此,它将匹配这两个: MOUSE_lion

我需要一种方法来匹配目录中的文件名

例如,我有三个文件:

CAt_DoG_ZebRa.TXT
MOUSE_lion_deer_BIRD.TXT
fIsh_biRD_LION.TXT
我无论如何都不是正则表达式专家,但是我以前在SnapLogic和Pentaho中使用过类似的东西:

(?i).*(?=.*bird)(?=.*lion).*.TXT
上述内容将匹配所有包含单词“bird”和“lion”的文件名,忽略大小写,单词的顺序无关紧要。非常强大!因此,它将匹配这两个:

MOUSE_lion_deer_BIRD.TXT    
fIsh_biRD_LION.TXT
我尝试了上面的许多变体,并与find和grep结合使用,但都无济于事。例如:

find . -regex ".*/(?i).*(?=.*bird)(?=.*lion).*.TXT"
上述发现与任何内容都不匹配

有人能推荐一种方法吗?

首先,它不支持PCRE正则表达式引擎,因此这是一种解决您问题的方法,使用and(递归):

此解决方案适用于任何顺序中匹配bird和lion的所有文件名

shopt -s globstar   # enable recursive globs
shopt -s nocaseglob # make globs case-insensitive
for file in ./**/*bird*lion*.txt; do
  echo "found: $file"
done
…或者,如果你不在乎这些词之间的顺序:

shopt -s globstar   # enable recursive globs
shopt -s nocaseglob # make globs case-insensitive
shopt -s extglob    # enable extended globbing syntax
for file in ./**/*@(bird*lion|lion*bird)*.txt; do
  echo "found: $file"
done

诀窍:当您使用“向前看”或“向后看”编写某个正则表达式时,请对此表示怀疑,或者更改另一种编写方式,或者考虑正则表达式是否适合解决此问题。

那么您希望匹配包含lion或bird的文件吗?ie
猫、狗、斑马
不包括在内,因为它们同时包含狮子和鸟。是的,Cat_dog_zebra将不包括在内。据我所知,在任何
Find
的实现中,Find的
-regex
默认情况下都不是PCRE(您在此处编写代码的语法)。在GNU系统上,如果你看到手册页,你会看到一个
-regextype
,让你选择你想要的语法。也就是说,我不知道你为什么需要regex来做这个。如果常规globs不能做到这一点,extglobs可以做到——而bash 4或zsh则具有足够强大的globbing语法,即使在递归情况下也不需要
find
。他只想在文件中同时包含两个单词时才匹配文件。您需要在第一个解决方案中将OR改为AND。在你的第二个解决方案中,把正则表达式改回他所拥有的,它应该可以工作。他只想匹配一个同时包含两个单词的文件。这不是他想要的。@BrianStephens,编辑;现在它确实存在(如果文件多次包含这两个词中的一个,则可能会包含重复的结果)。@BrianStephens,…而且,现在,甚至连这个错误都没有。这应该可以很好地解决所有问题。很好。@CharlesDuffy我将您的代码放入脚本并尝试执行,但出现了一些错误:./match|u script.sh:第1行:shopt:globstar:找到了无效的shell选项名称:./***@(birdlion|lionbird)*.txt./match_script.sh:line 7:/home/mdusr:是一个目录–这里唯一有点遗憾的是读者可能不清楚使用
ls
只是一个示例,而不是一个良好实践的示例。(有关如何在脚本中使用
ls
导致bug的讨论,请参阅)。查找是必要的,因为它会强制它匹配两个单词,而您的不匹配。@CharlesDuffy-true。那太糟糕了。
shopt -s globstar   # enable recursive globs
shopt -s nocaseglob # make globs case-insensitive
shopt -s extglob    # enable extended globbing syntax
for file in ./**/*@(bird*lion|lion*bird)*.txt; do
  echo "found: $file"
done
# ls
asdafsdfdBirdasfdfd.txt      dasdbirdbfdgdlionb.txt       fgdfLionqweBirdaqw.txt   
# ls | /usr/gnu/bin/grep -i -E '.*(bird.*lion|lion.*bird).*\.txt'
dasdbirdbfdgdlionb.txt
fgdfLionqweBirdaqw.txt