Whitey Winn
Whitey Winn

Reputation: 306

Match file names using Linux Shell regex

I need a way to match file names in directory.

For example I have three files:

CAt_DoG_ZebRa.TXT
MOUSE_lion_deer_BIRD.TXT
fIsh_biRD_LION.TXT

I am not regex expert by any means, however I've used something like this in SnapLogic and Pentaho before:

(?i).*(?=.*bird)(?=.*lion).*.TXT

The above would match all file names that contain the words 'bird' and 'lion' with case being ignored and the order of the words would not matter. Very powerful! So it would match these two:

MOUSE_lion_deer_BIRD.TXT    
fIsh_biRD_LION.TXT

I tried lots of variations of the above in conjunction with find and grep to no avail. For example:

find . -regex ".*/(?i).*(?=.*bird)(?=.*lion).*.TXT"

The above find does not match anything.

Can anyone recommend a way to do this?

Upvotes: 6

Views: 8172

Answers (3)

Gilles Quénot
Gilles Quénot

Reputation: 185161

First, doesn't support PCRE regex engine, so this a solution for your problem, with and (recursive) :

 bash -c "shopt -s globstar; perl -lne 'print if /i.*bird/i and /i.*lion/i' **"

This solution work with all filenames matching bird and lion, in any orders

Upvotes: 1

Charles Duffy
Charles Duffy

Reputation: 295443

shopt -s globstar   # enable recursive globs
shopt -s nocaseglob # make globs case-insensitive
for file in ./**/*bird*lion*.txt; do
  echo "found: $file"
done

...or, if you didn't care about order between those words:

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

Upvotes: 7

Jason Hu
Jason Hu

Reputation: 6333

# ls
asdafsdfdBirdasfdfd.txt      dasdbirdbfdgdlionb.txt       fgdfLionqweBirdaqw.txt   
# ls | /usr/gnu/bin/grep -i -E '.*(bird.*lion|lion.*bird).*\.txt'
dasdbirdbfdgdlionb.txt
fgdfLionqweBirdaqw.txt

a trick: when you writing some regular expression using look ahead or look behind, doubt it, and either change another way to write it or think about whether regular expression is a suitable tool for this problem.

Upvotes: 2

Related Questions