4

suppose I write:

find . -regex "[0-9]{4}-[0-9]{2}-[0-9]{2}-(foo|bar).csv.gz" -printf "%f\n"

This command looks to me like it should work. I have iterated through the various regextype options and various regex formats, but am unable to get this sort of regex to work through find. Is there something simple I am getting wrong here regarding find and the regular expression parser?

4
  • 1
    As far as I know -name does not take regular expressions. You should use -regex or -iregex for that. See manuals for find: linux.die.net/man/1/find. – nobody Apr 1 '20 at 16:23
  • @meuh and the same applies for regex, just iterated though – Chris Apr 1 '20 at 16:24
  • The comment appeared while I was writing mine. I'm happy to delete mine if you'd rather post your own, @steeldriver. – terdon Apr 1 '20 at 17:04
  • @terdon no problem, already upvoted it ;) – steeldriver Apr 1 '20 at 17:23
12

Find's -name doesn't take regular expressions (this was used in the original version of the question). It takes shell globs, and that isn't a valid shell glob. You want to use the -regex test, but also need to tell it to use extended regular expressions or any other flavor that understands the {N} and foo|bar notations. Finally, unlike -name, the -regex test looks at the entire pathname, so you need something like this:

$ find . -regextype posix-extended -regex ".*/[0-9]{4}-[0-9]{2}-[0-9]{2}-(foo|bar).csv.gz" -printf "%f\n"
5678-34-56-bar.csv.gz
1234-12-12-foo.csv.gz

If you want to use -name, you could do:

find . \( \
       -name "[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]-foo.csv.gz" \
    -o -name "[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]-bar.csv.gz" \
       \) -printf "%f\n"
3

Another option is the fd tool:

fd '[0-9]{4}-[0-9]{2}-[0-9]{2}-(foo|bar).csv.gz'

https://github.com/sharkdp/fd

2

If you have reasonable filenames (at least in this folder) you could run something along the lines of

 find . | grep -E '[0-9]{4}-[0-9]{2}-[0-9]{2}-(foo|bar).csv.gz'

This way you can benefit from the a variety of grep options.

1
  • Even for non-reasonable ones, actually: find . -print0 | grep -z -E '[0-9]{4}-[0-9]{2}-[0-9]{2}-(foo|bar).csv.gz' | tr '\0' '\n'. That will replace the nulls with newlines so the output might be a little hard to parse, but at least it can deal with any file name. – terdon Apr 1 '20 at 17:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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