2

I need to use find to locate a file matching a regex pattern in filename.extension instead of the default, which matches /path/to/filename.extension.

For instance:

/folder
  |--a-love-song.ogg
  |--a-jazz-song.ogg
  +--love-songs
       +--a-blues-song.ogg

And I want to find, in /folder and it's sub-directories, files with .*love.* in the filename:

debian@debian:~$ find folder -regex ".*love.*"
folder/a-love-song.ogg
folder/love-songs                   # Shouldn't be returned
folder/love-songs/a-blues-song.ogg  # Shouldn't be returned

I read the man page and realize there is the option -name, which searches only the filename, but it does not seem to allow regex, and -name -regex does not work.

I tried using regex to ignore the path:

debian@debian:~$ find folder -regex "\/.*love.*$"

But it didn't return anything. Of course ls | grep would work, but it doesn't return the path to the file, which I need in order to know where the file is.

2 Answers 2

2

You mention that ls with grep would work if you got the full path to the file, how about find and grep? Because grep returns a line if a match is found anywhere in that line, your regex can match something that lacks /s before the filename and still contains your search string.

$ find folder | grep -i '[^/]*love[^/]*\.[a-z0-9]*'

That seems to work for me. The extension match can be reduced if you know all of your extensions lack numbers or if you know all of the files you want to match have a specific extension.


Example usage

$ find folder
folder
folder/a-love-song.ogg
folder/love-songs
folder/love-songs/a-blues-song.ogg
folder/love-songs/another-love-song.ogg
$ find folder | grep -i '[^/]*love[^/]*\.[a-z0-9]*'
folder/a-love-song.ogg
folder/love-songs/another-love-song.ogg

Attempted explanation of regex

  • [^/]*: Matches any number of characters that are not /
  • love[^/]*: Matches the string love and then any number of characters that are not /
  • \.[a-z0-9]*: Matches a . and then any number of letters or digits

Put together, [^/]*love[^/]*\.[a-z0-9]* matches with as many non-/ characters on either side of love with an extension tacked onto the end. Given the string a/love/path/love-file.ogg the above regex only matches love-file.ogg. If a leaf-folder contains love, for example: a/path/love-leaf, it does not match because love-leaf contains no . followed by letters or numbers.

2
  • Neat. Do you mind explaining what sorcery you did there? I mean, the regex part.
    – Alex
    Apr 15, 2013 at 1:36
  • @Alex I can try! If you're still confused, I recommend regexpal.com. It is a great resource to visualize regular expressions and what they match.
    – Rain
    Apr 15, 2013 at 1:48
0
find dir -regex '.*/[^/]*love[^/]*$'
3
  • That did not returned anything (yes I replaced dir with the directory).
    – Alex
    Apr 15, 2013 at 0:40
  • Fixed the regex. Apr 15, 2013 at 0:47
  • @grawity This still returns dir/love-songs (or any leaf directory with love in it). I'm not sure if it is possible to what @Alex wishes with just find alone.
    – Rain
    Apr 15, 2013 at 1:15

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .