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, 2020 at 16:23
  • @meuh and the same applies for regex, just iterated though
    – Chris
    Apr 1, 2020 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, 2020 at 17:04
  • @terdon no problem, already upvoted it ;) Apr 1, 2020 at 17:23

3 Answers 3

14

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, 2020 at 17:34

You must log in to answer this question.

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