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.
7 Answers
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.
2 Comments
$mydate such that the second line reads date --date="$(printf "01 %s" "$mydate")" +"%Y-%m" as otherwise Oct 2011 becomes Oct2011printf ? I'v tried as date --date="01 $mydate" +"%Y-%m" which seems to yield the same result but maybe I'm oversimplifying just to run into some corner cases later.read mon year <<< "Oct 2012" date -d "$mon 1 $year" "+%Y-%m" Result:
2012-10 3 Comments
read command, as "1 Oct 2012" is an accepted input format for date: dateStr="Oct 2012"; date -d "1 $dateStr" "+%Y-%m"when using an option to specify date(s), any non-option argument must be a format string beginning with '+'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 Comments
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} 1 Comment
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`"