Dan
Dan

Reputation: 537

Unix convert Month name to number

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

Answers (7)

Corry
Corry

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

tharrrk
tharrrk

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

L. D. James
L. D. James

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

Fredrik Pihl
Fredrik Pihl

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

Davide Berra
Davide Berra

Reputation: 6568

read mon year <<< "Oct 2012"
date -d "$mon 1 $year" "+%Y-%m"

Result:

2012-10

Upvotes: 11

Srini K
Srini K

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

jim mcnamara
jim mcnamara

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

Related Questions