We have code that generates a large number of files with names like stdout, stdout.qsub, stderr, stderr.foo, etc.

I would like to do

find <dir> -name (stdout|stderr) -exec ...

and only find stdout and stderr files, no stdout.qsub, etc.

So I can't do '-name "std*"'. In this case, I can do '-name "std[eo][ru][rt]"', and it works because there won't be any stdeut files to be found by that search.

Is there a cleaner way to do this than '-name "std[eo][ru][rt]"'?


1 Answer 1

find "$dir" \( -name stdout -o -name stderr \) -exec ...

Or, with GNU find:

find "$dir" -regextype posix-extended -regex ".*/(stdout|stderr)" 

Just note that -regex matches against the whole path, more like -path than -name and the regexp is anchored as if there was an implicit ^ at the start and $ at the end. Also beware that since .* matches any sequence of characters, it won't find stdout / stderr files in directories whose path cannot be decoded as characters in the locale.

Also beware it will fail if $dir starts with - or happens to match the name of a find predicate.

With BSD find, you can do:

find -E -f "$dir" -- -regex '.*/std(out|err)'

Above, the "$dir" is passed as an argument to the -f option, so there's no ambiguity and no problem with values of $dir starting with -. -E enables extended regexps like for grep or sed.

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