Essentially, I want to know how to run 2 (or more) find commands in one - an "or" search rather than an "and":
find . -name "*.pem"
find . -name "*.crt"
Essentially, I want to know how to run 2 (or more) find commands in one - an "or" search rather than an "and":
find . -name "*.pem"
find . -name "*.crt"
find
’s “or” operator is -o
:
find . -name "*.pem" -o -name "*.crt"
It is short-circuiting, i.e. the second part will only be evaluated if the first part is false: a file which matches *.pem
won’t be tested against *.crt
.
-o
has lower precedence than “and”, whether explicit (-a
) or implicit; if you’re combining operators you might need to wrap the “or” part with parentheses:
find . \( -name "*.pem" -o -name "*.crt" \) -print
In my tests this is significantly faster than using a regular expression, as you might expect (regular expressions are more expensive to test than globs, and -regex
tests the full path, not only the file name as -name
does).
While I was typing up this question, it occurred to me that find uses globbing rather than regex by default. But I bet there's a way to use regex!
Sure enough...I had to change the regextype to use posix-extended but that got me what I wanted.
find . -regextype posix-extended -regex ".*pem|.*crt"
Qaplah!
time
at the start to analyse whether you're faster using regex or wildcards. If you're searching over files might be worth using locate
.
– pbhj
Jan 24 '19 at 14:16
".*pem|.*crt"
finds a name that ends with pem or crt, not a file with those extensions. You'll need .*\.pem|.*\.crt
for that. But using regex for this isn't a good method anyway
– phuclv
Jan 24 '19 at 14:17
-regex
is applied to the whole pathname and because unanchored regular expressions may match anywhere in the given string.
– Kusalananda
Jan 24 '19 at 14:49
find
.
– chepner
Jan 24 '19 at 20:45