2

I have a directory where daily subdirectories are created, literally named according to $date. How can I delete folders and their contents that are older than 7 days according to the YYYYMMDD in the file name and not the metadata date? Say I have (skipped some for brevity):

20170817
20170823
20170828
20170901

I would end up with the following folders (which those should keep):

20170828
20170901

I created a variable that holds the date 7 days ago: dt_prev=$(date -d "`date`-7days" +%Y%m%d)

My thought was to ls -l a list of these folder names and compare row by row, but this involves cleaning that list, etc., and I figure there has to be an easier way.

0

4 Answers 4

5

I think the solution would be a simpler version of what glenn jackman posted, e.g.

seven_days=$(date -d "7 days ago" +%Y%m%d)
for f in [0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]; do
   [ -d "$f" ] || continue
   (( $f < $seven_days )) && echo rm -r "$f"
done

Remove the echo if the results look correct.

The -d test ensures that we only inspect (remove) directories.

3
  • Thanks @Jeff -- this works great. Is there any reason why this would not work via ssh? When I ssh to a remote server to delete similar sub-directories, the code simply does not work even with absolute paths. It actually tries to find the folder [0-9]..[0-9]. code: for f in [0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]; do echo absolute/path/on/remote/server/"$f" done result: absolute/path/on/remote/server/[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]
    – kstats9pt3
    Commented Sep 6, 2017 at 13:30
  • It assumes that you're running that snippet in the directory that has the dated directories in it. either cd /absolute/path/on/remote/server first, or prefix the [0-9]'s with the /absolute/path
    – Jeff Schaller
    Commented Sep 6, 2017 at 13:43
  • the [0-9] bits are single-digit shell globs, so work in much the same way as * or ? do.
    – Jeff Schaller
    Commented Sep 6, 2017 at 13:44
0

You should not parse ls, instead you can do something like this:

for f in *; do test "$f" -lt "$date" && do something; done

For your example, for the following directories and date=20170825:

$ ls
20170817  20170823  20170828  20170901
$ for f in *; do test "$f" -lt "$date" && echo "$f"; done
20170817
20170823
2
  • 1
    This may pick up things (not just directories) that have numerical names less than the dates, and it will error out on non-numerical names. And if any name corresponds to a shell variable whose value is numerical, that value will be used...
    – Kusalananda
    Commented Sep 1, 2017 at 18:34
  • The question implies that the directory contains only numbered sub directories, so the solution is a simplified one without checks, but you are right about the file names.
    – resc
    Commented Sep 1, 2017 at 18:40
0

With single find command:

date_week_ago=$(date -d "7 days ago" +%Y%m%d)
find . -type d -regextype posix-extended -regex '.*/[0-9]{8}$' \
       -exec bash -c 'd=$(basename {}); (( '$date_week_ago' > $d )) && rm -rf "$d"' \;
0

Simply use find command.

find . -type d ! \( -name "$(date -d "-7 days" +%Y%m%d)" \
    $(eval printf "%s" "\" -o -name \
   \$(date -d -"{6..0}"days +%Y%m%d)\"") -o -name . \) -exec rm -rf -- '{}' +
  • Only diretories-type d
  • Only directors where their name are in older than 7 days of aging.
  • Delete that directory and its contents rm -rf -- '{}' at once +
0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .