pmverma
pmverma

Reputation: 1703

How to find files modified in last 24 hr but do not find from hidden directories and sum them

I have following command to find files modified in last 24 hr and sum all of them.

#!/bin/bash

find /mnt/naspath -mtime 0 -print0 | du --files0-from=- -hc | tail -n1 >> /tmp/size.log
exit 0

However it does also sum the files form hidden directory under .snapshot

What i see in find man page is I can exclude .snapshot with following which I do not clearly understand.

#!/bin/bash

find . -name .snapshot -prune -o \( \! -name *~ -print0 \)

So now I hope to exclude hidden and sum modified file with following command but this is doing totally opposite. It exclude .snapshot but sum up rest of all. -mtime 0 is not being effected.

#!/bin/bash

find /mnt/naspath -mtime 0  -name .snapshot -prune -o \( \! -name *~ -print0 \) | du --files0-from=- -hc | tail -n1 >> /tmp/size.log

exit0

Anybody please know how to correct the command. Thanks

Upvotes: 0

Views: 786

Answers (1)

Triztan
Triztan

Reputation: 38

Solution

You could write it in two ways:

  1. Like 4ae1e1s comment above

    find /mnt/naspath -name .snapshot -prune -o \( -type f -mtime 0 -print0 \)
    

    In words:

    If name is '.snapshot' then prune, otherwise if type is file and modified in last 24 hrs, then -print0

  2. Alternatively

    find /mnt/naspath \! \(-name .snapshot -prune\) -type f -mtime 0 -print0
    

    In words:

    If not pruned (in case name was '.snapshot') and type is file and modified in last 24hrs, then -print0

Analysis

Ok, to understand, what went wrong in your second attempt, lets have another look at it

find /mnt/naspath -mtime 0  -name .snapshot -prune -o \( \! -name *~ -print0 \)

First we expand this in the way it is interpreted by find (i.e. inserting implicit -ands and respecting operator precedence (...) > \! > -and > -or). This results in:

find /mnt/naspath \( \
        \( -mtime 0 -and -name .snapshot \) -and -prune \
    \) -or \( \
        \( \! -name *~ \) -and -print0 \
    \)

The \s are only for escaping. This is now easier to understand - in words:

Any path matching -mtime 0 -and -name .snapshot will be pruned (i.e. skipped and not be descendet into, in case of a directory). For everything else which does not match -name *~ do -print0.

Obiously this does not match with your intention, because you only want to prune paths named .snapshot independent of their time of modification. The main reason for this different result is the placement of the -prune command and the rules for operator precedence. Instead the filter -mtime 0 should be applied for everything that was not pruned. Last but not least, the filter \! -name *~ does not do anything you wanted, instead you would need an additional filter -type f to exclude directories from the final count.

Note

Note: The expression -name .snapshot -prune should be the first expression to be executed.

For example -type f \! \(-name .snapshot -prune\) instead of \! \(-name .snapshot -prune\) -type f would lead to a different behaviour for non-files named .snapshot, like the directory in your case. As soon as -type f evaluates to false, find will stop evaluating the next expression (because it is implicitly linked with -and, which will never be true). The end result will be false in both cases, but prune will not be executed in the first case, which means sub-sequent descendance into '.snapshot' would not be prevented.

PS: I hope this explanation shed some light on your issue. Don't forget to vote, if you like this answer. :-)

Upvotes: 2

Related Questions