Reputation: 1494
I have a bunch of log files and I would like to keep only the last 3 (N) files, the most recent ones. How do you do this in bash elegantly?
I have this script but it's kind of long.
The files could be something like:
my-file-pattern.log.2019-10-01
my-file-pattern.log.2019-10-02
my-file-pattern.log.2019-10-03
and so on
My script:
#!/bin/bash
function keepLastNOnly(){
local WORKDIR="$1"
local PATTERN="$2"
local MAX=$3
cd $WORKDIR
COUNT=$(ls -t $WORKDIR | grep $PATTERN|wc -l|grep -o -E '[0-9]+')
while [ $COUNT -gt $MAX ]; do
local TODEL=$(ls -t $WORKDIR | grep $PATTERN |tail -n 1)
rm -rf "$TODEL"
COUNT=$(ls -t $WORKDIR | grep $PATTERN|wc -l|grep -o -E '[0-9]+')
done
}
keepLastNOnly "/MyDirectory/" "my-file-pattern.log" 3
Any shorter way?
Upvotes: 0
Views: 1594
Reputation: 3975
#!/bin/bash
function keepLastNOnly(){
local workdir="$1"
local pattern="$2"
local max="$3"
awk -v max="$max" '
NR<=max{ print "keeping " $0; next }
{ print "removing", $0
print |"rm -f " $0
}
' < <(find "${workdir}" -type f -name "${pattern}" | sort -r)
}
keepLastNOnly . "my-file-pattern.log*" 3
$ ./test.sh
keeping ./my-file-pattern.log.2019-10-08
keeping ./my-file-pattern.log.2019-10-07
keeping ./my-file-pattern.log.2019-10-06
removing ./my-file-pattern.log.2019-10-05
removing ./my-file-pattern.log.2019-10-04
removing ./my-file-pattern.log.2019-10-03
removing ./my-file-pattern.log.2019-10-02
removing ./my-file-pattern.log.2019-10-01
Upvotes: 0
Reputation: 1
Sort by time, new in a top. Skip 10 files in path, perform deletion of rest.
for rmfile in $(ls -lt /path/to/files/* | tail -n +11 | awk '{print $9}'); do
echo "Deleting file ${rmfile}"
rm -f ${rmfile}
done
Upvotes: 0
Reputation: 71
Keeping to the style of the question:
#!/bin/bash
function keepLastNOnly() {
local WORKDIR="$1"
local PATTERN="$2"
local MAX=$3
for file in `ls -t1 $WORKDIR | grep $PATTERN | head -n -3`; do
rm $file
done
}
The clue is the -n -3 flag to head.
Note that this version will keep the latest modified files, not the latest according to file name.
Upvotes: 3
Reputation: 37742
consider using logrotate
which does all that for you, you just need to configure it:
https://linux.die.net/man/8/logrotate
Upvotes: 2