What is the format of your log files? How do you determine the date of the last entry in the log? What do you want to do if the date of the last entry in two log files is the same?
-rw-rw-r-- 1 rails rails 44815467 Aug 3 04:02 pro.log.9.gz
I need to rename using "Aug 3" like pro.log.20120803.gz
My idea is to use a script like
for i in `ls *.gz`;
do
DAT=`ls -l $i | awk '{print $6 $7}'`
Here I need a logic on how to convert $DAT values to equivalent 20120803
into say $NDAT
FN=`ls $i | cut -d'.' -f1`
mv $FN $FN.log-$NDAT.gz
done
The following script should do what you want. It limits itself to features specified by POSIX, except for its use of the m[] associative array variable. This is a common feature in ksh on most available systems. If your ksh doesn't support associative array variables, it could easily be replaced by a function that would return a two digit string representing the abbreviated month name that would be passed in as an argument.
#!/bin/ksh
cm=$(date +%m) # current month as 2 deciml digits
cy=$(date +%Y) # current year as 4 or more decimal digits
ec=0 # final exit code
ly=$((cy - 1)) # last year as 4 or more decimal digits
typeset -A m # translation table abbreviated month name -> 2 digit month
m[Jan]=01; m[Feb]=02; m[Mar]=03; m[Apr]=04; m[May]=05; m[Jun]=06
m[Jul]=07; m[Aug]=08; m[Sep]=09; m[Oct]=10; m[Nov]=11; m[Dec]=12
for i in *.log.*.gz
do
$ According to POSIX, the last command in a pipeline MAY be run
# in a separate shell execution environment. It is forced into
# a separate execution environment here by the $(...) to make it
# portable to any system. The $(...) returns the value of $ec
# it isn't exported to the execution environment of the rest of
# this script otherwise. If any errors are reported in the
# subshell, their diagnostics are written to stderr (file
# descriptor 2). No output from the subshell is written to
# stdout (file descriptor 1). Note that if the move command is
# commented out and replaced by an echo, the echo output must be
# written to stderr! POSIX allows shells to run the last
# command in a mult-command pipeline in the current shell
# execution environment as an extension.
ls -l "$i" | ec=$( read x x x x x mnth day time file
if [ "$file" == "" ] # only true if ls failed
then printf "%s: ls failed: \"%s\"\n" "$0" "$i" >&2
if [ $ec -eq 0 ] # preserve exit code from a failed mv command
then ec=100
fi
echo $ec
continue
fi
mon=${m[$mnth]}
if [ "${time%:+([0-9])}" == "$time" ]
then # No <colon> in $time means $time is a year instead of a time
# because the date is in the future or more than six months old.
year=$time
elif [ "$mon" -gt $cm ]
then # $mon > $cm in the current year, assume it is last year
year=$ly
else year=$cy # otherwise, year is assumed to be current year
fi
new="$(printf "%s.log-%d%02d%02d.gz" "${file%%.log.*.gz}" \
$year $mon $day)"
if [ -e "$new" ] # true if $new already exists
then # print diagnostic; could concatenate log files instead
printf "%s: target exists: mv \"%s\" \"%s\" not executed\n" \
"$0" "$file" "$new" >&2
if [ $ec -eq 0 ] # preserve exit code from a failed mv command
then ec=101
fi
echo $ec
continue
fi
# exactly one of the next two lines must be a comment (# in column 1)
# mv "$file" "$new"
echo mv "$file" "$new" >&2
save=$?
if [ $save -ne 0 ]
then printf "%s: mv failed: mv \"%s\" \"%s\"\n" /
"$0" "$file" "$new" >&2
ec=$save
fi
echo $ec)
done
exit $ec
Note that the logic for setting the year to the previous year for entries
where ls -l displays the time of day instead of the year (for entries
less than six months old) hasn't been tested since this code was written
in the 2nd half of the year (and I didn't want to reset my system clock
to test this case).
Some systems will produce the output you specified.
Some systems don't provide a stat utility at all. I try to stick to POSIX standard behavior in the examples I post on this forum. I did use non-standard ksh array variables, but I documented that fact and don't know of any recent system that has a ksh that doesn't support them.
Agreed. Apple's stat(1) man page's description of how to do this is rather opaque and doesn't include any examples for this issue. But the command:
stat -t "%Y%m%d" -f "%Sm%n" file
does give output in the format needed for this script (YYYYMMDD) on OS X (and would greatly simplify the script I provided).
Although this site's OpenSolaris 2009.06 Man Page Set includes a stat(1) man page, I can't find a stat(1) man page for Solaris 10 or 11 and I don't remember there being a stat utility on the Solaris systems I used to use.