skimon
skimon

Reputation: 1179

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

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:

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

Upvotes: 5

Views: 124

Answers (2)

repzero
repzero

Reputation: 8412

piping this cut command cut -d ' ' -f 2- will take out the timestamp

simple example

echo '1450241538 ./Backup Set0'|cut -d ' ' -f 2-

will get rid of the timestamps

results will be

./Backup Set0

Upvotes: 0

Mr. Llama
Mr. Llama

Reputation: 20889

... | 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.

Upvotes: 3

Related Questions