Categories
Uncategorized

find(1) abuse

A colleague wanted to find all the files that end up *.disp or *.frag. Easy enough, right? In the shell you can say *.{disp,frag}.

$ ls *.{disp,frag}
foo.disp
foo.frag

Except that this doesn’t work with find:

$ find . -name '*.{disp,frag}'

Why not? Because braces aren’t globs, so they’re not supported by find(1).

What can you do instead?

Firstly, you can use the -regex flag.

$ find . -regex '.*.(disp|frag)'
./foo.disp
./foo.frag

This is particularly awful because find defaults to the emacs style of regexes (which took me ages to remember the details of) and means you end up with leaning toothpick syndrome. And you’re matching the whole filename, not a subset, so you have to have the .* on the front.

The second option is to use find’s expression language. Find THIS FILE or THAT FILE.

$ find . ( -name '*.disp' -or -name '*.frag' ) -print
./foo.disp
./foo.frag

This is a bit more readable, but you have to remember that the parentheses are quoted because the shell likes to munch on them. Overall, it does seem preferable to -regex though.

Like all these things, you can take it too far.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s