2

Run command

find /volume1/Ingest -not -name '*.txt' -mtime +1 -print

and got the following output

/volume1/Ingest/test/Cube Emergency Lighting Locations Aug 2018.pdf
/volume1/Ingest/Cube Microplex Live Recording info.pdf
/volume1/Ingest/stuff over 7 days will be automatically deleted.txt

But last files matches *.txt, what's going on?

4
  • 5
    Maybe invisible characters in file names like a space after .txt? Can you pipe the output to LC_ALL=C sed -n l (that's lowercase L). Also try with ! instead of that non-standard -not. Commented Jun 3 at 14:50
  • 1
    When using !, you mostly have to prevent the shell from expanding it, e.g. by prefixing it with a backslash so -not becomes \!. Commented Jun 3 at 14:58
  • Ben, please also tell us your operating system so we know what find flavor you have. Commented Jun 3 at 14:59
  • 2
    @Henriksupportsthecommunity, there's no shell where ! on its own is a problem. find's ! has been used fine for about 50 years. Commented Jun 3 at 16:17

2 Answers 2

1

If you want code rather than a suggestion for fixing the issue, which is that the unexpected filename in question may have trailing space or other non-printing characters embedded in it, here you go. This implements what I understand from your question, which is to delete files and directories that are older than a day:

#!/bin/bash

base='/volume1/Ingest'
days=1

# Find directories not modified for a day
readarray -d '' -t dirs < <(find "$base" -depth -type d -mtime +"${days:-1}" -print0)

# Check files in each directory
for dir in "${dirs[@]}"
do
    printf 'DIRECTORY %s\n' "$dir"
    find -- "$dir" -maxdepth 1 ! -type d ! -name '*.txt' -mtime +1 -printf 'DELETE %P\n' ## -delete

    if [ "$(find -- "$dir" -maxdepth 1 -printf '.' 2>/dev/null | wc -c)" -gt 1 ]
    then
        printf 'DELETE DIRECTORY %s\n' "$dir"
        ## rmdir -- "$dir"
    fi

    echo
done

This code will avoid *.txt files in every directory, per your question. You can remove or comment the printf statements in the Check files… loop if you want the process to be silent. Uncomment the two ## elements to delete your files and directories; otherwise it's just a reporting tool

0

Thanks for every bodies help. I ended up taking a different direction and thought I would share the code.

#!/bin/bash

DIR="/volume1/Ingest"
DAYS=1
KEEP="*.txt"

echo
echo "Refreshing modification time of top-level *.txt files"
find "$DIR" -maxdepth 1 -type f -name "$KEEP" -exec touch {} \;

for f in "$DIR"/$KEEP; do # list date owner and base filename
  [ -f "$f" ] && echo "$(date -r "$f" '+%d-%m-%y %H:%M') $(stat -c '%U' "$f") $(basename "$f")"
done

echo
echo "Deleting directories older than $DAYS day(s)"
find "$DIR" \( \
  -path "$DIR/#recycle" -o -path "$DIR/@eaDir" \
\) -prune -o -type d -mtime +$DAYS -exec rm -r -v {} +

echo
echo "Deleting files older than $DAYS day(s)"
find "$DIR" \( \
  -path "$DIR/#recycle" -o -path "$DIR/@eaDir" \
\) -prune -o -type f -mtime +$DAYS -exec rm -v {} +

Its to delete old files on a Synology NAS but keep *.txt files at top level.

1
  • 1
    Consider mkdir a a/b; touch a/b/c. Now consider that c is being updated frequently (say every few minutes). Your code here will delete a and its contents after $DAYS days despite it holding a file c that's still fresh and in use Commented Jun 7 at 15:23

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.