I would like to find all png AND jpg files and used the following command and no results are returned however if I replace -a
with -o
it shows me the list of files. Why is that?
`find . -maxdepth 1 \( -iname \*\.png -a -iname \*\.jpg \)
A logic error. What you're telling find
is:
find, in this folder, all files that are (PNG and JPG)
But, of course, there are no files that are both at the same time, which is why the -o
works:
find, in this folder, all files that are (PNG or JPG)
When constructing these queries just imagine find
passing each file to the test. Then apply boolean logic. So for example:
It finds a .txt file. It's not a PNG (false), and not a JPG (false), so false && false equals false
It finds is a .png file. It's a PNG (true), and not a JPG (false), so true && false equals false
It finds is a .jpg file. It's not a PNG (false), and it's a JPG (true), so false && true equals false
If you use the -o
switch, and it finds a .png file, then it's a PNG (true) and it's not a JPG (false), so true || false equals true.
-o
instead of -a
, like I said. If you don't get any results, then you're searching in the wrong directory.
-iname \*\.png
is looked at as 1 query followed by the second query of -iname \*\.jpg
?
Jan 15, 2013 at 7:20
find
will evaluate both "queries" to whether they're true or false, and then combine the result of both with the logic test (and/or). If the result is true
, the file is found. As I wrote in my example, if the first test is true
("It's a PNG!") and the second is false
("It's not a JPG!"), this evaluates to true
when combined with a logical or
.
-a is a logical AND meaning that the file name must end in both .PNG and .JPG to be true.
-o is a logical inclusive OR meaning the file name must end in .PNG or .JPG (or both) to be true.