Keeping the format ...

Hi all,

Am trying to execute a loop but having some troubles...
Files that will be query'd use the Julian date (eg: cpu032, cpu365) in their naming convention.

I'm a little lost how to maintain the three character format of the numeric portion of the file name while cycling backwards(or forwards for that matter) in a loop.

Something similar to the following:

xstart=`date '+%j'`
xend=`expr $xstart - 30`

while [ $xstart -gt $xend ] ; do

  echo $xstart
  xstart=`expr $xstart - 1`

done

If $xstart begins at 032 (1-Feb) and $xend becomes 002 (2-Jan) then I should see...
032
031
030
029
...
004
003
002

Unfortunately I'm not - and is only displaying the significant digits.
Is there any way around this??

Here's one that might help:

xstart=`date '+%j'`
xend=`expr $xstart - 30`
while [ $xstart -gt $xend ] ; do
if [ $xstart -lt 10 ]; then
echo 00"$xstart"
elif [ $xstart -lt 100 ]; then
echo 0"$xstart"
else
echo $xstart
fi
xstart=`expr $xstart - 1`
done

It's not the prettiest, but it does the trick.

Thanks seismic_willy,

I've already use the same techique in another script for reporting stats, but thought that there may have been another way.

Again, thanks. :slight_smile:

With ksh, just use "typeset -Z3 xstart" at the top of the script. Then ksh will maintain the leading zeros.

Thanks Perderabo,

Is there a similar way to do the same in `bash` ?

Bash does not support that option to typeset.
Also, if you're using a Linux-based OS, you most likely have PDKSH installed, instead of ksh. Most versions of pdksh do not support that either - only the "real" ksh can be trusted...

Good news though! You can get David Korn's KSH 93 from here:

Using AT&T's package is a bit of a pain, but it's worth it.

If you cannot use typeset, you can format it with awk:

#!/bin/sh

xstart=`date '+%j'`
xend=`expr $xstart - 30`

while [ $xstart -gt $xend ] ; do

  xname=`awk 'BEGIN {printf "%3.3d",'$xstart';exit}'`
  echo $xname
  xstart=`expr $xstart - 1`

done

Thanks heaps guys. :wink:
Will try to implement it when I go back to work later today.

Guys,

It's working great and I'm using Ksh for the script.

One quick question; is it possible to convert a Jullian date to a formatted date??

Ie : Jullian Date = 032
Formatted Date = 01/02/2002

I know it can be done, but I can't work out the logic for it... I'm not too hot at math logic.

Perderabo, any gems to contribute? :stuck_out_tongue:

First of all, we seem to be talking about "Day of Year" here rather than "Julian Date". I know it's pro forma for programmers to mix the two up, but to get this right we have to be precise.

Here is a page that discusses the real meaning of Julian Day. And here is Julian Day Calculator.

Converting a Julian Day Number to a date is rough but it can be done. Converting a Day of Year" to a date is impossible. We must also have the year. We need the year both so that we can display it and to determine if we are dealing with a leap year. Here is a script that takes to parameters, the year and the day of year and converts them to a date:

#! /usr/bin/ksh

#                ja fe ma ap ma ju ju ag se oc no de
set -A mlength   31 28 31 30 31 30 31 31 30 31 30 31

typeset -Z2 dmonth dday


year=$1
doy=$2

#
#  is this a leap year?
leap=0
if ((!(year%100))); then
	((!(year%400))) && leap=1
else
	((!(year%4))) && leap=1
fi
echo leap = $leap

#
#  set number of days in february
mlength[1]=28
((leap)) && mlength[1]=29
#
#  loop on month
month=0
mdoy=0
while ((month<12 && mdoy<doy)); do
	((oldmdoy=mdoy))
	((mdoy=mdoy+${mlength[month]}))
	((month=month+1))
done

((day=doy-oldmdoy))
dday=$day
dmonth=$month
echo "$dmonth/$dday/$year"
exit 0

This is my solution & works great.
Unfortunately I hadn't started gathering stats on the systems this macro is running on since the 16th January.
The scary part is that it took me less than a shift to finish. :slight_smile:
Note: This script is intended to run only on the 1st of any month.

#!/bin/ksh
typeset -Z3 xcjdate xpjdate xj31date xidl xpeak
typeset -Z2 xrptmth
#######################################################
# >> NOTE: Ensure that you comment ANY amendments. <<
#######################################################
#
# SCRIPT NAME : sarcpurpt
#               Creation of the Monthly CPU Report
#               based on data collected from the
#               previous month.
# ----------------------------------------------------
# PURPOSE:
# This macro is intended to be run via CRONTAB on the
# 1st of every month at 00:05.
#
# Files to be read.
# /amadeus_stats/sar/cpu/cpuJJJ.?
#
# Output File (Report).
# /amadeus_stats/sar/cpu/Reports/MMMYYYY.JJJHHMM
# n.b. - JJJ = Jilian date.
#        MMM = Short Month Name (Jan, Feb, etc.).
#       YYYY = Long Year.
#       HHMM = 24hr Time.
#          ? = CPU Indicator [ 1 , 2 , 3 , 4 ]
#
# ----------------------------------------------------
# AMENDMENTS:
# <DATE> <VER> <WHO> < COMMENTS                      >
# 260202  001   CJY  Initial script.
# 270202  002   CJY  Ready for production.
#
# ----------------------------------------------------
# >> NOTE: Ensure that you comment ANY amendments. <<
#######################################################

# - Environment setup ----------------------------------#

  ## File location/assignments.
  xcpudir=/amadeus_stats/sar/cpu/
  xrptdir=$xcpudir\Reports/
  ## Email Recipients.
  xemails="users@somedomain.com.au"

  ## Long Name Month Listing.
  lngmth="January February March April May June \
          July August September October November December"
  ## Short Name Month Listing.
  shtmth="Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec"

# - Functions ------------------------------------------#
#
function SendEmail {

  xsub="EVEREST-AU - CPU Monthly Detailed Report - "$2", "$3"."
  mail -s "$xsub" $xemails < $1

}  ## End-of-function SendEmail
#
# - START-OF-SCRIPT ------------------------------------#
##
  xcjdate=`date '+%j'`
  xpjdate=`expr $xcjdate - 1`
  xcurmth=`date '+%m'` ; xcuryr=`date '+%Y'`
  xrptmth=`expr $xcurmth - 1` ; xrptyr=`expr $xcuryr - 1`
  if [ $xrptmth -eq 0 ] ; then
    xshtmth=`echo $shtmth | cut -f12 -d" "`$xrptyr
    xlngmth=`echo $lngmth | cut -f12 -d" "`
  else
    xshtmth=`echo $shtmth | cut -f$xrptmth -d" "`$xcuryr
    xlngmth=`echo $lngmth | cut -f$xrptmth -d" "`
  fi
  if [ $xcjdate -eq 001 ] ; then
    xpjdate=366
    xj31date=`expr $xpjdate - 32`
  else
    xpjdate=`expr $xcjdate - 1`
    xj31date=`expr $xpjdate - 32`
  fi

  ## Set Report File Name.
  xcpurpt=$xrptdir/$xshtmth.`date '+%j%H%M'`
  ##
  ## Create Header.
  echo > $xcpurpt
  echo "SYSTEM: "`hostname`" (EVEREST-AU)" >> $xcpurpt
  echo "CPU Detailed Usage Report - "$xlngmth", "`echo $xshtmth | cut -c4-7` \
       "." >> $xcpurpt
  echo "--------------------------------------------------------\c" >> $xcpurpt
  echo "----------------------------------------------" >> $xcpurpt
  echo "             <----- CPU #1 ----->   <----- CPU #2 ----->\c" >> $xcpurpt
  echo "   <----- CPU #3 ----->   <----- CPU #4 ----->" >> $xcpurpt
  echo "Date       - %Avg %Peak Peak-Time - %Avg %Peak Peak-Time\c" >> $xcpurpt
  echo " - %Avg %Peak Peak-Time - %Avg %Peak Peak-Time" >> $xcpurpt
  while [ $xj31date -lt $xpjdate ] ; do

    for xfile in 1 2 3 4    # Number of CPU files for each day.
      do
        #-- Get Date of CPU report -----------------------------#
        xcpudd=`awk '/SCO_SV/' $xcpudir\cpu$xj31date.$xfile | cut -c36-37`
        xcpumm=`awk '/SCO_SV/' $xcpudir\cpu$xj31date.$xfile | cut -c33-34`
        xcpuyy=`awk '/SCO_SV/' $xcpudir\cpu$xj31date.$xfile | cut -c39-42`
        xcpudate="$xcpudd/$xcpumm/$xcpuyy"
        if [ $xcpumm -eq $xrptmth ] ; then
          xidl=`awk '/SCO_SV/,/Average/' $xcpudir\cpu$xj31date.$xfile |\
                tail -1 | cut -c38-40`
          xidl=`expr 100 - $xidl`
          xpeak=`awk '/SCO_SV/,/Average/' $xcpudir\cpu$xj31date.$xfile | \
               grep ':' | grep -v '%' | grep -v 'mpx restarts' | sort -k 5 | \
               head -1 | cut -c38-40`
          xpeak=`expr 100 - $xpeak`
          xtime=`awk '/SCO_SV/,/Average/' $xcpudir\cpu$xj31date.$xfile |\
               grep ':' | grep -v '%' | grep -v 'mpx restarts' |\
               sort -k 5 | head -1 | cut -c1-8`
          case $xfile in
          1) xcpu1=" "$xidl"   "$xpeak"  "$xtime" -";;
          2) xcpu2=" "$xidl"   "$xpeak"  "$xtime" -";;
          3) xcpu3=" "$xidl"   "$xpeak"  "$xtime" -";;
          4) xcpu4=" "$xidl"   "$xpeak"  "$xtime;;
          esac
        fi
      done
    if [ $xcpumm -eq $xrptmth ] ; then
      IFS=""
      echo $xcpudate" - "$xcpu1" "$xcpu2" "$xcpu3" "$xcpu4 >> $xcpurpt
      IFS=" "
    fi
    xj31date=`expr $xj31date + 1`
  done
  echo "--------------------------------------------------------\c" >> $xcpurpt
  echo "----------------------------------------------" >> $xcpurpt
  echo " End-Of-Report." >> $xcpurpt
  echo >> $xcpurpt
  echo " Nb: Print in Landscape mode suggested." >> $xcpurpt

  chown operator:group $xcpurpt
  chmod 644 $xcpurpt

  SendEmail $xcpurpt $xlngmth `echo $xshtmth | cut -c4-7`

##
# - END-OF-SCRIPT --------------------------------------#

And a sample of the output...

SYSTEM: www3.travel.com.au (EVEREST-AU)
CPU Detailed Usage Report - January, 2002 .
------------------------------------------------------------------------------------------------------
             <----- CPU #1 ----->   <----- CPU #2 ----->   <----- CPU #3 ----->   <----- CPU #4 ----->
Date       - %Avg %Peak Peak-Time - %Avg %Peak Peak-Time - %Avg %Peak Peak-Time - %Avg %Peak Peak-Time
16/01/2002 -  062   100  05:15:01 -  006   037  12:15:02 -  030   083  12:15:02 -  013   059  12:15:02
17/01/2002 -  070   100  05:15:01 -  006   055  14:15:17 -  030   092  14:01:29 -  012   073  14:01:29
18/01/2002 -  055   099  03:15:01 -  004   019  16:15:01 -  025   077  02:00:00 -  009   036  16:15:01
19/01/2002 -  037   100  04:45:06 -  001   004  05:30:02 -  013   072  02:00:00 -  002   024  05:30:02
20/01/2002 -  036   100  05:00:01 -  001   024  13:30:00 -  014   074  02:00:00 -  003   031  13:30:00
21/01/2002 -  054   100  05:00:01 -  004   018  11:00:00 -  025   075  02:00:01 -  008   028  15:45:00
22/01/2002 -  065   099  02:45:00 -  013   049  16:45:00 -  037   075  02:00:01 -  020   058  16:45:00
23/01/2002 -  064   098  02:45:00 -  005   030  11:45:00 -  033   077  02:00:00 -  012   045  11:45:00
24/01/2002 -  064   098  02:45:00 -  005   043  15:00:02 -  032   086  15:00:02 -  011   063  15:00:02
25/01/2002 -  064   098  02:45:00 -  005   026  10:30:01 -  031   076  02:00:00 -  011   044  10:30:01
26/01/2002 -  045   099  04:45:01 -  001   009  05:30:01 -  018   074  02:00:01 -  004   029  05:30:01
27/01/2002 -  040   098  02:45:01 -  001   017  17:45:00 -  016   076  05:30:01 -  004   027  02:00:00
28/01/2002 -  043   099  05:00:01 -  001   006  02:00:00 -  017   074  02:00:00 -  004   025  02:00:00
29/01/2002 -  062   099  02:45:00 -  005   038  16:15:00 -  029   079  16:15:00 -  011   056  16:15:00
30/01/2002 -  061   099  02:45:00 -  005   026  12:15:01 -  029   076  02:00:00 -  011   046  12:15:01
------------------------------------------------------------------------------------------------------
 End-Of-Report.

Ahh, just a smal oversite with the above script - an error.

The line ...
while [ $xj31date -lt $xpjdate ] ; do
should actually read ...
while [ $xj31date -le $xpjdate ] ; do

I only stpotted the error when the emails were missing the last day of the month - doh!

Yep. Check out a previous thread where I posted a script to convert to & from julian date values.