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.

4

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.

  • 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 Sep 6 '17 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 Sep 6 '17 at 13:43
  • the [0-9] bits are single-digit shell globs, so work in much the same way as * or ? do. – Jeff Schaller Sep 6 '17 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
  • 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 Sep 1 '17 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 Sep 1 '17 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 +

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.