find: "weird" regex behaviour

I have these two files in current dir:

  • oos.txt
  • oos_(copy).txt

I execute this find command:

find . -regex './oos*.txt'

And this outputs only the first file (oos.txt)! :confused:

Only if I add another asterisk to the find

find . -regex './oos*.*txt'

do I also get the second file (oos_(copy).txt).

What am I doing wrong? :rolleyes:

The correct thing should be:

find . -regex "./oos.*\.txt"

You're looking for any number of 's' before the dot ( that excludes the parentheses )

Why is the red dot (after "oos") needed?

find . -regex './oos.*\.txt'

It means any character so will match the parentheses .

1 Like

Yup... you can also use wildcards:

find -name "oos*.txt"
1 Like

In POSIX regular expressions, modifiers like * need a character before them to describe what they're modifying. . is a special character meaning 'match any character'. So .* means 'match any number of any character'.

I don't think you should be putting the path inside the expression. I don't think the path is actually part of what gets matched. You can limit what directories it goes inside with mindepth and maxdepth, to limit it to ./ that would be -mindepth 1 -maxdepth 1

If you use -name, you get behavior like you were expecting: find ./ -mindepth 1 -maxdepth 1 -name 'oos*.txt'

-iname acts like -name but is case-insenstive. It may be unavailable depending on your system, though.

1 Like

However,

$ find . -name 'oos*.txt'
./oos.txt
./oos_(copy).txt

works.

p.s. I did try your command, and did re-create the oddity you described. Just not sure about the -regex as part of a find command.

1 Like

You all deserve one BIG thank you.

The combination of .* is new to me: always seen these two in "XOR mode": look for one- (.) or many-(*) random characters.

find . -name 'oos*.txt'

indeed works fine.