views:

69

answers:

5

Hi,

I have a date value stored in a unix korn shell variable

VALUE="2010_09_23"

I want to change it to "23-Sep-2010" and store it in VALUE1. How can i do it?

VALUE1="23-Sep-2010"

A: 

This command does what you want on OSX:

VALUE1=$(date -j -f %Y_%m_%d +%d-%b-%Y "$VALUE")

If you are using a different Unix variant, the combination of options to date that you require may be different. The %-notation is well standardized (see man strftime) but the capabilities of the date command are not.

GNU coreutils date (what you get on Linux, and which may also be hiding somewhere on your "SunOS" system (I doubt you actually mean "SunOS", Sun Microsystems hasn't called its Unix variant that for about fifteen years, but even so, the stuff in /usr/bin is still incredibly obsolete junk) -- look in /usr/local and all subdirectories of /opt -- can also do this but you have to preprocess the input:

VALUE1=$(date -d $(echo $VALUE | tr _ -) +%d-%b-%Y)

This may also work, depending on exactly which shell you have:

VALUE1=$(date -d ${VALUE//_/-} +%d-%b-%Y)
Zack
Arav
Ran this command. I am getting
Arav
date: illegal option -- jdate: illegal option -- f
Arav
Augh, SunOS. You are up Ancient, Nonstandard Tools Creek (even if by "SunOS" you actually mean "Solaris", alas). fahd's Perl approach is probably your best bet. If you can find the GNU coreutils somewhere on your system, that version of `date` might be persuaded to do the job, but its `-d` option has a hardwired parser that doesn't understand "2010_09_23", so you'd have to preprocess it (see my edited answer).
Zack
+1  A: 

Ksh has a built-in date formatting capability through the printf builtin. The documentation isn't clear about how the argument should be formatted; the following works in my ksh 93s+:

VALUE1=$(printf "%(%02d-%b-%Y)T\n" "${VALUE//_/-}")
Gilles
VALUE1=$(printf "%(%02d-%b-%Y)T\n" "${VALUE//_/-}")-bash: printf: `(': invalid format character
Arav
getting an error invalid format character
Arav
@Arav: Your question specifically targeted ksh, and so did my answer. Bash doesn't have any corresponding feature. If you have neither ksh nor better-than-POSIX date, I think your best option is to do it manually (hard-coding month names).
Gilles
@Gilles, could be he just doesn't have ksh version 93
glenn jackman
@glenn: Could be (the feature was introduced in ksh 93h, released in 1999), except that no ksh would not complain with `bash: … invalid format character`.
Gilles
A: 
VALUE="2010_09_23"
VALUE1="$( gawk -v date="$VALUE" 'BEGIN {
    gsub(/_/, " ", date)
    print strftime("%d-%b-%Y", mktime(date " 00 00 00"))
}')"
glenn jackman
VALUE1="$( gawk -v date="$VALUE" 'BEGIN {> gsub(/_/, " ", date)> print strftime("%d-%b-%Y", mktime(date " 00 00 00"))> }')"-bash: gawk: command not found
Arav
am getting gawk not found
Arav
Unless you can get your sysadmin to install it, I'd go with @schot's or @fahd's answer.
glenn jackman
A: 

Using Perl:

echo 2010_09_23 |  perl '-MPOSIX qw(strftime)'  -le'
    @dt = split /_/,<STDIN>;
    print strftime( "%d-%b-%Y",0,0,0,$dt[2],$dt[1]-1,$dt[0]-1900);
  '

Output:

23-Sep-2010
dogbane
+1  A: 

Using portable awk and a hardcoded list of month names. The substr calls work around a tricky issue is the interpretation of the numbers '08' and '09' in some awk implementations: Are they the decimal numbers '8' and '9' or invalid octal numbers?

echo "$VALUE" | awk -F'_' '
    BEGIN {
        OFS="-"
        split("Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec", m)
    }
    {
        $2 = 10 * substr($2, 1, 1) + substr($2, 2, 1)
        print $3, m[$2], $1
    }'
schot