Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

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.

share|improve this question

2 Answers 2

up vote 1 down vote accepted

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.

share|improve this answer
    
Neat. Do you mind explaining what sorcery you did there? I mean, the regex part. –  Alex Apr 15 '13 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 '13 at 1:48
    
Ooh I get it now, thank you! –  Alex Apr 15 '13 at 2:08
find dir -regex '.*/[^/]*love[^/]*$'
share|improve this answer
    
That did not returned anything (yes I replaced dir with the directory). –  Alex Apr 15 '13 at 0:40
    
Fixed the regex. –  grawity Apr 15 '13 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 '13 at 1:15

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.