1

I tried to create this one liner bash script which finds and then deletes directories older than X days based on their file names and code works flawlessly if directory exist. The only issue is that if directory doesn't exist, it tries to delete it as well erroring out:

find: ‘/var/www/html/resources/cache/2022-02-08’: No such file or directory

Although I have put the condition which checks if the directory exists in result of find command and then delete it.

find '/var/www/html/resources/cache/' -type d -name '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]' -exec sh -c 'd={}; [ "$(date -d "6 days ago" +%Y-%m-%d)" ">" "$(basename $d)" ] && [ -d $d ] && rm -rf $d' \;

Let's say I have following directories located at /var/www/html/resources/cache

2022-02-08
2022-02-09
2022-02-10
2022-02-11
2022-02-12
2022-02-13
2022-02-14
2022-02-15

[ "$(date -d "6 days ago" +%Y-%m-%d)" ">" "$(basename $d)" ] checks if file name is older than 6 days

[ -d $d ] checks if it's a directory

3 Answers 3

0

You can use xargs command instead of -exec option of find.

find '/var/www/html/resources/cache/' -type d -name '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]' | xargs -I {} sh -c 'd={}; [ "$(date -d "6 days ago" +%Y-%m-%d)" ">" "$(basename $d)" ] && [ -d $d ] && rm -rf $d'

The code block above will work, but it may return 123 as the value. xargs command returns 123 when there is an error in any repeated commands. So error happens if there is even one directory name was not six days ago.

find '/var/www/html/resources/cache/' -type d -name '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]' | xargs -I {} sh -c 'd={}; if [ "$(date -d "6 days ago" +%Y-%m-%d)" ">" "$(basename $d)" ]; then [ -d $d ] && rm -rf $d; fi'

You can replace the condition with if statements to solve this problem.

1
  • Thankyou. Exactly what I was looking for. Feb 15 at 10:57
0

You can convert the date six days ago to seconds, convert the directory name to seconds, and perform a direct numeric comparison. Since you're considering only the topmost directories, you don't really need find at all and you can just iterate across the directories with a standard loop

ago=$(date --date "6 days ago" +%s)
for dir in /var/www/html/resources/cache/[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]
do
    [ -d "$dir" ] || continue

    this=$(date --date "${dir##*/}" +%s)
    [ $this -lt $ago ] && echo "DELETE $dir"
done

If you really want to use find, this version requires GNU find or another version that understands -maxdepth. (If you don't have such a find there are ways to emulate -maxdepth.)

find /var/www/html/resources/cache -maxdepth 1 -name "[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]" -exec sh -c '
    ago=$(date --date "6 days ago" +%s)
    for dir in "$@"
    do
        this=$(date --date "${dir##*/}" +%s)
        [ $this -lt $ago ] && echo "DELETE $dir"
    done
' _ {} +

Output from both alternatives

DELETE /var/www/html/resources/cache/2022-02-08
DELETE /var/www/html/resources/cache/2022-02-09

When you're ready, change the echo statement to rm -rf or whatever you prefer.

0

Testing directories with timestamp:

~] ls -alFh
drwxr-xr-x 11 root root 4.0K Feb 15 10:51 ./
drwxr-xr-x  3 root root 4.0K Feb 15 10:51 ../
drwxr-xr-x  2 root root 4.0K Feb 15 10:51 2022-02-08/
drwxr-xr-x  2 root root 4.0K Feb 15 10:51 2022-02-09/
drwxr-xr-x  2 root root 4.0K Feb 15 10:51 2022-02-10/
drwxr-xr-x  2 root root 4.0K Feb 15 10:51 2022-02-11/
drwxr-xr-x  2 root root 4.0K Feb 15 10:51 2022-02-12/
drwxr-xr-x  2 root root 4.0K Feb 15 10:51 2022-02-13/
drwxr-xr-x  2 root root 4.0K Feb 15 10:51 2022-02-14/
drwxr-xr-x  2 root root 4.0K Feb 15 11:01 2022-02-15/
drwxr-xr-x  2 root root 4.0K Feb 15 10:51 2022-02-16/

regexp in find

For find a directories with regexp, you can use:

~] find . -type d -regextype posix-extended -regex '\./2022-02-[01][12345890]'
./2022-02-13
./2022-02-09
./2022-02-14
./2022-02-08
./2022-02-11
./2022-02-12
./2022-02-10
./2022-02-15

Time condition in find

Time conditions in find - the best way is to use -newerXY

-newerXY reference

Compares the timestamp of the current file with reference.  The reference argument is normally the name of a file (and one of its timestamps is used for the comparison) but it may also be a string describing an absolute time.

X and Y are placeholders for other letters, and these letters select which time belonging to how reference is used for the comparison.

              a   The access time of the file reference
              B   The birth time of the file reference
              c   The inode status change time of reference
              m   The modification time of the file reference
              t   reference is interpreted directly as a time

Some combinations are invalid; for example, it is invalid for X to be t.  Some combinations are not implemented on all systems; for example B is not supported on all systems.  If an invalid or unsupported combination of XY is specified, a fatal error results.  Time specifications are interpreted as for the argument to the -d option of GNU date.  

If you try to use the birth time of a reference file, and the birth  time  cannot  be determined, a fatal error message results.  If you specify a test which refers to the birth time of files being examined, this test will fail for any files where the birth time is unknown.

example:

~] find . -type d -regextype posix-extended -regex '\./2022-02-[01][12345890]' ! -newermt "2022-02-15 10:52:00" -print 
./2022-02-13
./2022-02-09
./2022-02-14
./2022-02-08
./2022-02-11
./2022-02-12
./2022-02-10

Delete directories

~] find . -type d -regextype posix-extended -regex '\./2022-02-[01][12345890]' ! -newermt "2022-02-15 10:52:00" -exec rm -r {} \;
find: ‘./2022-02-13’: No such file or directory
find: ‘./2022-02-09’: No such file or directory
find: ‘./2022-02-14’: No such file or directory
find: ‘./2022-02-08’: No such file or directory
find: ‘./2022-02-11’: No such file or directory
find: ‘./2022-02-12’: No such file or directory
find: ‘./2022-02-10’: No such file or directory
~] ls -alFh
total 16K
drwxr-xr-x 4 root root 4.0K Feb 15 11:13 ./
drwxr-xr-x 3 root root 4.0K Feb 15 10:51 ../
drwxr-xr-x 2 root root 4.0K Feb 15 11:01 2022-02-15/
drwxr-xr-x 2 root root 4.0K Feb 15 10:51 2022-02-16/

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.