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?

0

4 Answers

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.

2

Here is one way to do your first version:

find -type f -regex ".*/.*\.\(shtml\|css\)" 
0

You need to parenthesize to only include files:

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

Bonus: this is POSIX-compliant syntax.

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

1

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy