Substract 1 Month from MonthID

Hi,
I am writing a small unix command to substract one month from the MonthID.
If MonthID = 201301 the below script returns me 201212

 
if [[ `echo $monthid | cut -c5-6` == 01 ]] then
a=`echo $monthid | cut -c1-4`
b=`expr $a - 1`
c=12
echo "$b$c"
else 
a=`echo $monthid | cut -c5-6`
b=`expr $a - 1`
c=`echo $monthid | cut -c1-4`
echo "$c$b"
fi 

Problem exists when MonthID=201307 and i run the above script and it returns 20136 instead of 201306
Help is appreciated to get the MonthID in correct format.

substitute echo for printf

printf "%d%02d\n" $c, $b
1 Like

Hi pinnacle,
I find this very confusing.

You haven't said what shell or operating system you're using, but from the [[ expression ]] , I assume that you're not using a Bourne shell and that you are probably using bash or ksh .

But, your code sample doesn't define MonthID (or monthid ). And the way you define MonthID in the description of what you're trying to do (with spaces around the equals sign in MonthID = 201301 won't work with any shell that I know of that supports [[ ... ]] .

If my assumptions are correct:

  1. You are using a Korn shell, a bash shell, or another shell that recognizes POSIX arithmetic expansions, and
  2. you want to work with a variable named MonthID , not monthid ,

then the following should do what you want MUCH more efficiently:

MonthID=${1:-201301}
printf 'Starting MonthID: %d\n' "$MonthID"
MonthID=$((MonthID - 1))
if [ $((MonthID % 100)) -eq 0 ]
then	MonthID=$((MonthID - 88))
fi
printf "Ending MonthID: %d\n" "$MonthID"

In fact, with a bash or ksh shell, it can be simplified further to:

MonthID=${1:-201301}
printf 'Starting MonthID: %d\n' "$MonthID"
if [ $((--MonthID % 100)) -eq 0 ]
then	((MonthID -= 88))
fi
printf "Ending MonthID: %d\n" "$MonthID"

Hi Aia,
There is no need for the comma in $c, , and with some shells having a comma there will generate a syntax error.

2 Likes

Thanks Don Cragun !!
I am planning to use this as a single command in ETL tool (DataStage).
The operating system I am using is AIX.

Output of oslevel command gives : 6.1.0.0

Out of the 2 solutions that you provided only the first solution workson my side.

I am planning to use the 1st solution, but it I had a little concern, will this command work if unix admin apply some patch in future? Or should I be using the script that I created since it only uses very basic commands??

Appreciate your reply on this.

Also I have modified the command little bit to suit my needs as follows:

 
 
MonthID=$output; MonthID=$((MonthID - 1)); if [ $((MonthID % 100)) -eq 0 ]; then MonthID=$((MonthID - 88)); fi; printf "%d\n" "$MonthID"

Note: MonthID here will be set by output of another ETL process.

Appreciate your reply on my questions.

There shouldn't be any reason to avoid the above constructs on your current or future releases of AIX. You can also get rid of the 1st command in your script:

MonthID=$((output - 1)); if [ $((MonthID % 100)) -eq 0 ]; then MonthID=$((MonthID - 88)); fi; printf "%d\n" "$MonthID"