Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I am attempting to locate files that match a particular pattern however attempting to run the command below returns no results even though there are files that should match the pattern.

find . -maxdepth 1 -regextype posix-extended -regex ".*/s_[a-zA-Z]_[a-zA-Z]\.png" -exec echo {} \;

I know that the .*/ to match the whole path but don't quite understand what that means exactly.

The files it has to match for example include

  1. s_choose_blue.png
  2. s_choose_red.png
  3. s_new_blue.png
share|improve this question
up vote 1 down vote accepted

The actual problem with your regular expression is that it doesn't match what it's supposed to match. To break it down:

  • .*/ – any character, multiple times, followed by a slash. This basically consumes the directory list before the actual file name, so it'd literally match ./ (as in your example), but also ./some/other/dir/, up until the last slash.

    This works because regular expressions are "greedy" by default, meaning that they match as much as they can. In essence, this part allows you to just search for the actual file name and strip the path from the result.

    To summarize, you need the .*/ in front of the regex if all you care about is the actual file name. If you need to match some parts of the path to the file as well, you cannot use .*/

  • s_ – this works just fine in your example

  • [a-zA-Z] – this only consumes one character from this class

  • _ – followed by an underscore

  • [a-zA-Z] – again followed by one character

  • \.png – literally match the dot and the extension

So, you have to change your regex to:


You'll have to use the +, which basically says, one or multiple of the previous.

share|improve this answer
@slhck- Ah...Silly me. I knew I had to be missing something. Thanks for pointing it out. I still don't understand the use of .*/. Can you give me examples? Why is it needed? Can I do without it? When would I need to use it? – PeanutsMonkey Jan 11 '13 at 8:29
I edited my answer. Since regular expressions are greedy, .* matches anything until the last slash in the file's full path, so you basically eliminate everything except the actual file name. In your special case, where maxdepth is 1, using \./ would have worked as well since you would just need to literally match ./ because there are no other subdirectories. – slhck Jan 11 '13 at 8:33
Sorry am still a little lost. I know that .* match any number of characters, multiple times and this then followed by a slash. So for example I have the files located in the directory Downloads. If I understood you correct, using .*/ would be that mean that find finds ./(the current directory)/subdirectory1/subdirectory2/filename.png Is that right? Assuming that is right using the find command as-is e.g find . -maxdepth 1 \*\.png already returns the results ./filename.png or ./directory1/filename.png – PeanutsMonkey Jan 11 '13 at 8:40
I just tried find . -maxdepth 1 -regextype posix-extended -regex ".*/s_[a-zA-Z]+_[a-zA-Z]+\.png" -exec echo {} \; and I still get no results. – PeanutsMonkey Jan 11 '13 at 8:43
Works for me, but maybe you could just give me the raw output of find . -maxdepth 1? In any case, just imagine that .*/ slurps everything until the last slash. Your example above didn't contain Downloads, so I don't know what exactly you mean, sorry. Also, note that the dot . is your current directory already, so ./(the current directory)/ doesn't make sense. Finally, remember that the regex only matches what find would output and gives you a subset of that. The regex, simply said, does not influence what find actually "finds". – slhck Jan 11 '13 at 8:46

You must log in to answer this question.

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