Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

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?

share|improve this question
add comment

4 Answers 4

up vote 16 down vote accepted

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.

share|improve this answer
    
That will also print directories named "*.css". –  Teddy Apr 1 '10 at 6:30
1  
And here is how to fix @Teddy's issue: find . -type f \( -name "*.shtml" -or -name "*.css" \) (personally, I would escape the asterisks as the OP did (fewer characters less Shift). –  Chris Johnsen Apr 1 '10 at 6:39
    
@Chris and @Teddy: Thanks, I updated it. –  Benjamin Bannier Apr 1 '10 at 13:16
    
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 1 '10 at 20:07
    
/me had his coffee now –  Benjamin Bannier Apr 1 '10 at 20:11
add comment

Here is one way to do your first version:

find -type f -regex ".*/.*\.\(shtml\|css\)"
share|improve this answer
    
Thank you for the regex and fewest keystrokes. –  Dave Jarvis Apr 1 '10 at 2:07
    
Like always a answer very to the point. –  Benjamin Bannier Apr 1 '10 at 2:33
add comment

You need to parenthesize to only include files:

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

Bonus: this is POSIX-compliant syntax.

share|improve this answer
add comment

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)$/ 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.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.