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?
# 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.
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
First, find doesn't support PCRE regex engine, so this a solution for your problem, with perl and bash (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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With