60

What is the correct syntax for:

find . -type f -name \*.\(shtml\|css\)

This works, but is inelegant:

find . -type f -name \*.shtml > f.txt && find . -type f -name \*.css >> f.txt

How to do the same, but in fewer keystrokes?

Dave Jarvis
  • 3,168
  • 5
  • 32
  • 37

4 Answers4

83

You can combine different search expressions with the logical operators -or or -and, so your case can be written as

find . -type f \( -name "*.shtml" -or -name "*.css" \)

This also show that you do not need to escape special shell characters when you use quotes.

Edit

Since -or has lower precedence than the implied -and between -type and the first -name put name part into parentheses as suggested by Chris.

Benjamin Bannier
  • 16,044
  • 3
  • 43
  • 41
  • That will also print directories named "*.css". – Teddy Apr 01 '10 at 06:30
  • Hmm, the parentheses in your updated version are a bit misplaced. The individual parentheses need to end up as separate parameters to *find*, so they need spaces around them (` "*.css"\) ` results in a single string value; it is the same as (e.g.) ` '*.css)' `). Second, the parentheses need to go around whole ‘primaries’ (the open parenthesis needs to be before `-name`, not between it and its ‘operand’). – Chris Johnsen Apr 01 '10 at 20:07
19

Here is one way to do your first version:

find -type f -regex ".*/.*\.\(shtml\|css\)"
Dennis Williamson
  • 106,229
  • 19
  • 167
  • 187
15

You need to parenthesize to only include files:

find . -type f \( -name "*.shtml" -o -name "*.css" \) -print

Bonus: this is POSIX-compliant syntax.

Teddy
  • 6,848
  • 4
  • 19
  • 19
4

I often find myself ending up using egrep, or longer pipes, or perl for even more complex filters:

find . -type f | egrep '\.(shtml|css)$'
find . -type f | perl -lne '/\.shtml|\.css|page\d+\.html$/ and print'

It may be somewhat less efficient but that isn't usually a concern, and for more complex stuff it's usually easier to construct and modify.

The standard caveat applies about not using this for files with weird filenames (e.g. containing newlines).

reinierpost
  • 2,220
  • 1
  • 18
  • 23
  • +1 for a clean and modular solution, the performance bottlenecks usually occur while processing the files resulted from the search results. – Cristik Jan 31 '18 at 17:53