Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't find let me match multiple patterns?

I'm writing some bash/zsh scripts that process some files. I want to execute a command for each file of a certain type, and some of these commands overlap. When I try to find -name 'pattern1' -or -name 'pattern2', only the last pattern is used (files matching pattern1 aren't returned; only files matching pattern2). What I want is for files matching either pattern1 or pattern2 to be matched.

For example, when I try the following this is what I get (notice only ./foo.xml is found and printed):

$ ls -a
.        ..       bar.html foo.xml
$ tree .
.
├── bar.html
└── foo.xml

0 directories, 2 files
$ find . -name '*.html' -or -name '*.xml' -exec echo {} \;
./foo.xml
$ type find
find is an alias for noglob find
find is /usr/bin/find

Using -o instead of -or gives the same results. If I switch the order of the -name parameters, then only bar.html is returned and not foo.xml.

Animated version

Why aren't bar.html and foo.xml found and returned? How can I match multiple patterns?

like image 782
Cornstalks Avatar asked Feb 04 '15 20:02

Cornstalks


People also ask

What is pattern matching problem?

Uses of pattern matching include outputting the locations (if any) of a pattern within a token sequence, to output some component of the matched pattern, and to substitute the matching pattern with some other token sequence (i.e., search and replace).

How do I match a pattern in regex?

2.1 Matching a Single Character The fundamental building blocks of a regex are patterns that match a single character. Most characters, including all letters ( a-z and A-Z ) and digits ( 0-9 ), match itself. For example, the regex x matches substring "x" ; z matches "z" ; and 9 matches "9" .

What is ?: In regex?

It indicates that the subpattern is a non-capture subpattern. That means whatever is matched in (?:\w+\s) , even though it's enclosed by () it won't appear in the list of matches, only (\w+) will.


1 Answers

You need to use parentheses in your find command to group your conditions, otherwise only 2nd -name option is effective for -exec command.

find . \( -name '*.html' -or -name '*.xml' \) -exec echo {} \;
like image 87
anubhava Avatar answered Sep 28 '22 06:09

anubhava