Understanding escaped parentheses in find
Asked Answered
D

1

7

I've cobbled together what is below, and it seems to work, with the possible exception of the "! -empty". One thing I'm learning (as I go) is that just because something works, doesn't mean it's right or formed correctly...The question I have is how do you determine what requires parentheses and what doesn't in a find command?

In OS X, -and is "implied by the juxtaposition of two expressions it does not have to be specified"

My goal is to have find: find directories that are over 5 minutes old, not empty, and are not .dot (hidden -i.e. "." and "..")

count="$( find . -type d -mmin +5 \! -empty \( ! -iname ".*" \) | wc -l )"
echo $count
if [ "$count" -gt 0 ] ; then
    echo $(date +"%r") "$cust_name loc 9: "${count}" directories exist to process, moving them" >> $logFILE
    find . -type d -mmin +5 \! -empty \( ! -iname ".*" \) | xargs -I % mv % ../02_processing/

    cd $processingPATH

    # append the time and the directories to be processed in files_sent.txt
    date +"---- %a-%b-%d %H:%M ----" >> $filesSENTlog
    ls >> $filesSENTlog

    find . -type f -print0 | xargs -0 /usr/local/dcm4che-2.0.28/bin/dcmsnd $aet@$peer:$port
    echo $(date +"%r") "$cust_name loc 10: Processing ${count} items..." >> $logFILE

    # clean up processed studies > from processing to processed
    echo $(date +"%r") "$cust_name loc 11: Moving ${count} items to 03_processed" >> $logFILE
    mv * $processedPATH
else
    echo $(date +"%r") "$cust_name loc 12: there are no directories to process" >> $logFILE
fi

could I just do:

find . -type d -mmin +5 \! -empty \! -iname ".*"

? or is that not correct for some reason?

Donatello answered 21/6, 2014 at 6:1 Comment(2)
So your question boils down to: is find . -type d -mmin +5 \! -empty \! -iname ".*" equivalent to find . -type d -mmin +5 \! -empty \( ! -iname ".*" \) - right?Tie
That, and what determines the use of parentheses. What would also help is, what is the proper term for the use of the parentheses specifically in find. I don't really understand it's usage -so I'll search when I can figure out what it's specifically called... and finally, is it good, bad, or ugly? :-)Donatello
Q
18

find has the following operators listed in order of precedence (highest -> lowest)

  1. ()
  2. !|-not
  3. -a|-and
  4. -o|-or
  5. , (GNU only)

Note: All tests and actions have an implied -a linking each other

So if you are not using any operators, you don't have to worry about precedence. If you are just using not like in your case, you don't really have to worry about precedence either, since ! exp exp2 will get treated as (! exp) AND (exp2) as expected, due to ! having higher precedence than the implied and.

Example where precedence matters

> mkdir empty && cd empty && touch a && mkdir b
> find -mindepth 1 -type f -name 'a' -or -name 'b'
./a
./b

The above got treated as find -mindepth 1 (-type f AND -name 'a') OR (-name 'b')

> find -mindepth 1 -type f \( -name 'a' -or -name 'b' \)
./a

The above got treated as find -mindepth 1 (-type f) AND ( -name 'a' OR -name 'b')

Note: Options ( i.e. -mindepth, -noleaf, etc... ) are always true

Conclusion

The following two uses of find are exactly the same

  • find . -type d -mmin +5 \! -empty \( ! -iname ".*" \) | wc -l
  • find . -type d -mmin +5 \! -empty \! -iname ".*" | wc -l

Both get treated as

  • find . (-type d) AND (-mmin +5) AND (! -empty) AND (! -iname ".*") | wc -l
Quire answered 21/6, 2014 at 7:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.