LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices


Reply
  Search this Thread
Old 06-07-2017, 12:33 AM   #1
samasat
LQ Newbie
 
Registered: Nov 2011
Location: Bangalore
Distribution: Ubuntu/Cygwin
Posts: 29

Rep: Reputation: Disabled
find command with use of -not and -or ; why the order matters


I am trying to understand why the results differ if I use -not -path to exclude the "Exclude" directory from the search before and after the -iname conditions.

For referece , all files with *.bmp, *.png and *.jpg file extension:
Code:
$ find . -type f -iname "*.bmp" -or -iname "*.png" -or -iname "*jpg" |wc
  28770   28895 1247623
If I use -not to exclude the "Exclude" directory upfront:
Code:
$ find . -type f -not -path "*Exclude*"  -iname "*.bmp" -or -iname "*.png" -or -iname "*jpg"|wc
  28128   28241 1203962
If I use the -not condition at the end:
Code:
$ find . -type f -iname "*.bmp" -or -iname "*.png" -or -iname "*jpg" -not -path "*Exclude*"|wc
  28715   28840 1244863
I wanted to understand why there is difference - first I found 28128 files with -not being upfront and then I get 28715 if the -not is kept in the end?
 
Old 06-07-2017, 01:24 AM   #2
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 20,772

Rep: Reputation: 7058Reputation: 7058Reputation: 7058Reputation: 7058Reputation: 7058Reputation: 7058Reputation: 7058Reputation: 7058Reputation: 7058Reputation: 7058Reputation: 7058
the best way to understand is to check the difference. Did you get just more files, or a different set of files?

Last edited by pan64; 06-07-2017 at 01:25 AM. Reason: typo
 
1 members found this post helpful.
Old 06-07-2017, 01:24 AM   #3
Turbocapitalist
LQ Guru
 
Registered: Apr 2005
Distribution: Linux Mint, Devuan, OpenBSD
Posts: 7,005
Blog Entries: 3

Rep: Reputation: 3633Reputation: 3633Reputation: 3633Reputation: 3633Reputation: 3633Reputation: 3633Reputation: 3633Reputation: 3633Reputation: 3633Reputation: 3633Reputation: 3633
Between every pair of options that does not have an -or has an implied -and whether you write it or not. The precedence of -or and -and is quite different. Remember your boolean logic.

Perhaps you meant this?

Code:
$ find . -type f -\( iname "*.bmp" -or -iname "*.png" -or -iname "*jpg" \) -print |wc
 
1 members found this post helpful.
Old 06-07-2017, 02:48 AM   #4
aragorn2101
Member
 
Registered: Dec 2012
Location: Mauritius
Distribution: Slackware
Posts: 567

Rep: Reputation: 301Reputation: 301Reputation: 301Reputation: 301
Hi,

If you read the man pages for find, you actually see:

Code:
expr1 -o expr2
    Or; expr2 is not evaluated if expr1 is true.

expr1 -or expr2
    Same as expr1 -o expr2, but not POSIX compliant.
So, I experimented a bit and the command acts literally how it is explained above. Since you have several "-or", the first expression is being evaluated for sure. Some of the subsequent ones are being ignored if the previous expression is true. If you test this command with a less populated directory where you can actually examine the output without wc, you will see that in the case where the exclusion comes at the end, the command actually does not exclude the path since one or more of the previous "or" expressions were true.

Last edited by aragorn2101; 06-07-2017 at 02:50 AM.
 
1 members found this post helpful.
Old 06-07-2017, 08:25 AM   #5
rknichols
Senior Member
 
Registered: Aug 2009
Distribution: CentOS
Posts: 4,740

Rep: Reputation: 2198Reputation: 2198Reputation: 2198Reputation: 2198Reputation: 2198Reputation: 2198Reputation: 2198Reputation: 2198Reputation: 2198Reputation: 2198Reputation: 2198
Quote:
Originally Posted by samasat View Post
If I use -not to exclude the "Exclude" directory upfront:
Code:
$ find . -type f -not -path "*Exclude*"  -iname "*.bmp" -or -iname "*.png" -or -iname "*jpg"|wc
  28128   28241 1203962
If I use the -not condition at the end:
Code:
$ find . -type f -iname "*.bmp" -or -iname "*.png" -or -iname "*jpg" -not -path "*Exclude*"|wc
  28715   28840 1244863
I wanted to understand why there is difference - first I found 28128 files with -not being upfront and then I get 28715 if the -not is kept in the end?
The "-and" operator (whether written or implied) has higher precedence than "-or", so in the first expression, the "-type f" and "*Exclude*" terms bind only to the "*.bmp" term. It is equivalent to this:
Code:
find . \( -type f -and -not -path "*Exclude*" -and -iname "*.bmp" \) -or -iname "*.png" -or -iname "*jpg"
In your second version, the "-type f" binds only to the "*.bmp" term, and the "*Exclude*" term binds only to the "*jpg" term. It is equivalent to
Code:
find . \( -type f -and -iname "*.bmp" \) -or -iname "*.png" -or \( -iname "*jpg" -and -not -path "*Exclude*" \)
Neither one is what you probably intended. Try
Code:
find . -type f -not -path "*Exclude*" \( -iname "*.bmp" -or -iname "*.png" -or -iname "*jpg" \)
(In all cases, the "*jpg" was probably intended to be "*.jpg", but I've stayed with what you wrote.)

Last edited by rknichols; 06-07-2017 at 08:27 AM.
 
1 members found this post helpful.
Old 06-19-2017, 12:34 AM   #6
samasat
LQ Newbie
 
Registered: Nov 2011
Location: Bangalore
Distribution: Ubuntu/Cygwin
Posts: 29

Original Poster
Rep: Reputation: Disabled
@pan64 since this happened with some large database of files containing thousands of files, I found it difficult to learn it by looking through the file list. Creating a separate trial db was more work without clarity at that point to ensure that it will reproduce the same behavior.

Thank you very much for the explaining the root cause Turbocapitalist, Aragorn2101, and rknichols.

Yes, rknichols .. I actually meant "*.jpg"


Thanks once again!
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Logi Sales Manager on Ncurses (invoice, invoicing, orders, order, sale order, sales order...)? Xeratul Linux - Software 0 03-25-2017 02:45 PM
Order of arguments of slackpkg matters? slalik Slackware 2 12-30-2016 08:53 AM
How to optimise "find" command, order of parameters postcd Linux - General 5 02-07-2014 09:50 AM
Find command - result order laki47 Linux - Newbie 1 01-20-2011 07:17 AM
do you find #include order to be arbitrary? ta0kira Programming 2 08-29-2008 12:02 AM

LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie

All times are GMT -5. The time now is 07:13 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration