I have the following path:
/dir1/dir2/
In this path I have the following directories containing various (not relevant) application detrius:
follower1234 1-Dec-2018
follower3456 2-Dec-2018
follower4567 3-Dec-2018
follower7890 9-Jan-2019
follower8901 10-Jan-2019
leader8765 4-Dec-2018
bystander6789 5-Dec-2018
Assume that today is 10 Jan 2019.
Assume that there can be any number of followerXXXX
, leaderXXXX
and bystanderXXXX
directories.
What I want is to delete all followerXXXX
directories but the latest followerXXX
directory, that are older than two weeks old.
Now I can delete all directories older than a particular date. But that isn't my question. I'm adding two additional parameters.
In this case I want to delete:
follower1234 1-Dec-2018
follower3456 2-Dec-2018
follower4567 3-Dec-2018
But not
follower7890 9-Jan-2019
follower8901 10-Jan-2019
leader8765 4-Dec-2018
bystander6789 5-Dec-2018
ie I want to delete files
(a) matching a pattern
(b) older than two weeks
(c) not the latest directory matching the pattern (ie keep the last one)
My question is: How to delete all directories in a directory older than 2 weeks except the latest one that match a file pattern?
Best Answer
Introduction
The question has been modified.
My first alternative (the oneliner) does not match the new specification, but saves the newest directory among the directories that are old enough to be deleted (older than 14 days).
I made a second alternative, (the shellscript) that uses
@ seconds since Jan. 1, 1970, 00:00 GMT, with fractional part.
and subtracting the seconds corresponding to 14 days to get a timestamp for the 'limit-in-seconds' at
seclim
in the sorted list of directories.1. Oneliner
The previous answers are clean and nice, but they do not preserve the newest
follower
directory. The following command line will do it (and can manage names with spaces but names with newlines create problems),tested on this directory structure,
like so,
So
follower9
is excluded because it is the newestfollower
directory (directories with names, that do not start withfollower
(leader1
,leader2
and2
are not in the game).Now we add the time criterion,
-mtime +14
and do another 'dry run' to check that it works like it should, when we have changed directory to where there are realfollower
directories,Finally we remove
echo
and have a command line that can do what we want,find
in the current directory, directories with names beginning withfollower
, that are not modified since 14 days ago.head -n -1
will exclude the newestfollower
directory.xargs
as parameters torm -r
in order to remove the directories, that we want to remove.2. Shellscript
I made a second alternative, (the shellscript) that uses
It has also two options,
-n
dry run-v
verboseI modified the shellscript according to what the OP wants: enter the pattern as a parameter within single quotes e.g. 'follower*'.
I suggest that the name of the shellscript is
prune-dirs
because it is more general now (no longer onlyprune-followers
to prune directoriesfollower*
).You are recommended to run the shellscript with both options the first time in order to 'see' what you will do, and when it looks correct, remove the
-n
to make the shellscript remove the directories that are old enough to be removed. So let us call itprune-dirs
and make it executable.follower
subdirectoriesprune-dirs
and run with the two options
-v -n
Test
I tested
prune-dirs
in a directory with the following sub-directories, as seen withfind
Usage
Run with
-v -n
(a verbose dry run)A verbose dry run with a more general pattern
Run without any options (a real case removing directories)
Run with
-v
'trying again'The shellscript lists no directory 'above' "limit-in-seconds", and there are no files listed for the
rm -r
command line, so the work was done already (which is the correct result). But if you run the shellscript again several days later, some new directory may be found 'above' "limit-in-seconds" and be removed.