Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

removing all but X oldest directories on FreeBSD via Bash (no -printf, with spaces, no zsh)

Tags:

bash

freebsd

There are several different topics on stackoverflow regarding find/removing the oldest directory/files in a directory . I have read a lot of them and seen a myriad different ways that obviously work for some people on other systems but not for me in my particular case.

The constraints are:

  • Im on FreeBSD (Freenas 9.3)
  • Directories have spaces in them
  • Dont use ls (http://mywiki.wooledge.org/ParsingLs)
  • Cannot use -printf of find (doesnt exist for me)

The closest i have gotten is something like this (not complete):

find . -maxdepth 1 -d -name "Backup Set*" -print0 | xargs -0 stat -f "%m %N" | sort -r| awk 'NR>5'

This gives me the directories that I want to delete however they now have timestamps prepended, which I am not sure that if i strip out and pipe to rm i will be back to a situation where i cannot delete directories with spaces in them.

output:

1450241540 ./Backup Set1
1450241538 ./Backup Set0

Thanks for any help here.


relevant posts that I have looked at:

https://superuser.com/questions/552600/how-can-i-find-the-oldest-file-in-a-directory-tree

Bash scripting: Deleting the oldest directory

Delete all but the most recent X files in bash

like image 269
skimon Avatar asked Oct 19 '22 19:10

skimon


1 Answers

... | awk 'NR>5' | while read -r timestamp filename; do rm -rf "${filename}"; done

When there are more fields than variables specified in read, the remainder is simply lumped together in the last specified variable. In our case, we extract the timestamp and use everything else as-is for the file name. We iterate the output and run an rm for each entry.

I would recommend doing a test run with echo instead of rm so you can verify the results first.


Alternately, if you'd prefer an xargs -0 version:

... | awk 'NR>5' | while read -r timestamp filename; do printf "%s\0" "${filename}"; done | xargs -0 rm -rf

This also uses the while read but prints each filename with a null byte delimiter which can be ingested by xargs -0.

like image 125
Mr. Llama Avatar answered Nov 18 '22 06:11

Mr. Llama