Reputation: 537
In BASH shell scripting or using gdate, given a date like "Oct 2011" how do I convert to a year-month number format? Output should be "2011-10", for example.
Upvotes: 11
Views: 46868
Reputation: 41
case "`date | awk '{print $2 }'`" in
Jan) MON="01" ;;
Feb) MON="02" ;;
Mar) MON="03" ;;
Apr) MON="04" ;;
May) MON="05" ;;
Jun) MON="06" ;;
Jul) MON="07" ;;
Aug) MON="08" ;;
Sep) MON="09" ;;
Oct) MON="10" ;;
Nov) MON="11" ;;
Dec) MON="12" ;;
esac
echo $MON
Upvotes: 4
Reputation: 361
Let's kick this dead horse. If you don't care about invalid month names you can use this function I've written which is quite short (and only does 1 exec) but expects a month to be valid english 3-chars lower or upper case and only requires GNU sed and bash:
m2n() { echo $((-10+$(sed 's/./\U&/g;y/ABCEGLNOPRTUVY/60AC765A77ABB9/;s/./+0x&/g'<<<${1#?}) ));}
For your example I'd do:
read m y <<<"$@"; echo "$y-`m2n $m`"
Upvotes: 1
Reputation: 1719
You can convert the month to a number by finding the position of the name string:
#!/bin/bash
month=Oct
months="JanFebMarAprMayJunJulAugSepOctNovDec"
tmp=${months%%$month*}
month=${#tmp}
monthnumber $((month/3+1))
printf "%02d\n" $monthnumber
The output of the script above is:
10
Your specific string you could code:
#!/bin/bash
mydate="Oct 2011"
monthnumber() {
month=$1
months="JanFebMarAprMayJunJulAugSepOctNovDec"
tmp=${months%%$month*}
month=${#tmp}
monthnumber=$((month/3+1))
printf "%02d\n" $monthnumber
}
arr=(`echo ${mydate}`);
month=$(monthnumber ${arr[0]})
year=$(echo ${arr[1]})
echo "$year-$month"
The output would be:
2011-10
Upvotes: 5
Reputation: 45670
Bash4 supports hash-tables (answer by Jim is the correct one though).
Example
#!/bin/bash
declare -A months=( ["Jan"]="01" ["Feb"]="02" )
mydate="Jan 2011"
echo ${mydate:4:8}-"${months["${mydate:0:3}"]}"
Output:
2011-01
Upvotes: 2
Reputation: 6568
read mon year <<< "Oct 2012"
date -d "$mon 1 $year" "+%Y-%m"
Result:
2012-10
Upvotes: 11
Reputation: 3365
I'm not sure if there is a shorter way of doing this, but here is one way. This is by no means fool proof. You can improve this by adding other checks to input and make the comparison case insensitive.
#!/bin/ksh
### Validate input
if [ $# -eq 0 ]
then
echo "Usage: $0 InputMonYYYY"
echo "Example: $0 \"Oct 2011\""
exit 1
fi
### Read input
INPUTSTR=$1
MON_STR=`echo $INPUTSTR |cut -d' ' -f1`
YYYY_STR=`echo $INPUTSTR |cut -d' ' -f2`
if [[ "$MON_STR" = "Jan" ]] then
MON_NUM=01
elif [[ "$MON_STR" = "Feb" ]] then
MON_NUM=02
elif [[ "$MON_STR" = "Mar" ]] then
MON_NUM=03
elif [[ "$MON_STR" = "Apr" ]] then
MON_NUM=04
elif [[ "$MON_STR" = "May" ]] then
MON_NUM=05
elif [[ "$MON_STR" = "Jun" ]] then
MON_NUM=06
elif [[ "$MON_STR" = "Jul" ]] then
MON_NUM=07
elif [[ "$MON_STR" = "Aug" ]] then
MON_NUM=08
elif [[ "$MON_STR" = "Sep" ]] then
MON_NUM=09
elif [[ "$MON_STR" = "Oct" ]] then
MON_NUM=10
elif [[ "$MON_STR" = "Nov" ]] then
MON_NUM=11
elif [[ "$MON_STR" = "Dec" ]] then
MON_NUM=12
fi
echo ${YYYY_STR}-${MON_NUM}
Upvotes: 2
Reputation: 16389
mydate="Oct 2011"
date --date="$(printf "01 %s" $mydate)" +"%Y-%m"
The parse_datetime interface for GNU date (which is what the example uses) has lots of rules. the Oct 2011 form of the date isn't one of them, so you prepend a "01 " to the front of it and date likes it.
Upvotes: 21