4

I'm trying to search for all files given a certain string / regex value. So if I were to say search for all files that have "hello" in the name, how would I go about doing this? Ever more complex, how would I go about finding a file whose name begins with any two letters followed by a dash and then a number?

I've tried the find command and that has helped in the situation of hello. I would just type find <dir> *hello* but this doesn't work with the regex values.

If I type find -E <dir> -regex '^[a-z]{2}-[1-9]' nothing happens. Even if I type find -E <dir> -regex '*[0-9]*', nothing happens.

Could someone help me with this? Thanks in advance

2
  • 3
    If you use -regex you'l have to operate regular expression but pattern matching. So -regex '.*[0-9].*'. Additionally note that -regex mean -wholepath so .*/[a-z][a-z]-[1-9].* would work.
    – Costas
    Aug 17, 2016 at 8:42
  • Thanks that makes sense. I managed to get it to work by using the last command. Also, I believe the single quotation marks are important as well. Not using them doesn't output anything
    – GoodPie
    Aug 17, 2016 at 8:47

2 Answers 2

3

-regex matches on the whole file path (not just the name), and is anchored by default (^ and $ implicit).

Here, you don't need regexps though, you can use the standard -name which takes a wildcard pattern and matches on the file name, not path:

find . -name '*hello*' -name '[[:alpha:]][[:alpha:]]-[1-9]*'

For file names that start with 2 letters, a hyphen and a digit from 1 to 9 and contain "hello".

With regexps, and here with FreeBSD/OS/X find, that would have to be:

find -E . -regex '.*hello[^/]*' -regex '.*/[[:alpha:]]{2}-[1-9][^/]*'

You need [^/]* instead of .* as otherwise, that would match on ./aa-9/hello/foo/bar for instance.

In any case, find <dir> *hello* doesn't do what you think it does. The shell expands that *hello* glob to the list of non-hidden files or directories in the current directory whose name contains "hello" and passes the result as extra arguments to find.

2

That fails because *[0-9]* is a glob and not a regex. In globs, * means "0 or more characters". However, in regular expressions, * means "0 or more of whatever is before the *". In other words, * is a quantifier and is only relevant if it is quantifying something.

So, the regex that matches 0 or more characters, then 0 or more numbers is .*[0-9]*. Additionally, when using -regex with find, the regular expression is matched against the entire pat of the file, so you need to take that into account. Putting all this together, what you are looking for is:

find /path/to/dir -regex '.*/[a-z][a-z]-[1-9]‌​.*'

Finally, you must always quote such constructs when passing them to find. If you don't, the shell will expand them (so * becomes the list of all files and directories in your current directory) before passing them to find.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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