1

I have a file: ifile.txt

83080603   55  72
87090607   83  87
88010612   82  44
89080603   55  72
00110607   83  87
01030612   82  44
05120618   84  44

The 1st column shows the date and time with the format YYMMDDHH.

I would like to print the first column as hrHDDMMMYYYY ofile.txt

03H06Aug1983   55  72
07H06Sep1987   83  87
12H06Jan1988   82  44

and so on

I can't able to convert the digit month-year to text month. My script is

awk '{printf "%s%5s%5s\n",
substr($0,7,2)"H"substr($0,5,2)substr($0,3,2)substr($0,1,2), $2, $3}' ifile.txt
Kay
  • 1,957
  • 2
  • 24
  • 46

4 Answers4

3

EDIT: Adding solution as per OP's comment for adding year as per condition here.

awk -v curr_year=$(date +%y) '
BEGIN{
  num=split("Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec",arr,",")
  for(j=1;j<=num;j++){
    key=sprintf("%02d",j)
    months[key]=arr[j]
  }
}
{
  year=substr($1,1,2)>=00 && substr($1,1,2)<=curr_year?"20":"19"
  $1=substr($1,length($1)-1)"H"substr($1,length($1)-3,2) months[substr($1,3,2)] year substr($1,1,2)
  print
  year=""
}
' Input_file


Could you please try following, written on mobile and successfully tested it on site https://ideone.com/4zYMu7 this also assume that since your Input_file first 2 letters denote year and you want to print only 19 in case there is another logic to get exact year then please do mention it

awk '
BEGIN{ 
  num=split("Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec",arr,",")
  for(j=1;j<=num;j++){
    key=sprintf("%02d",j)
    months[key]=arr[j]
  }
}
{
  $1=substr($1,length($1)-1)"H"substr($1,length($1)-3,2) months[substr($1,3,2)] "19" substr($1,1,2)
  print
}
' Input_file
RavinderSingh13
  • 130,504
  • 14
  • 57
  • 93
  • Yes, my data has year after 2000, which is not being considered here. For example `00110607` should print `07H06Nov2000` . – Kay Jul 04 '20 at 02:39
  • @Kay, could you please do lemme know how we could recognize if it should print 19 or 20? – RavinderSingh13 Jul 04 '20 at 04:45
  • Would it be possible to apply a condition, if `YY >= 00 then YYYY=20YY, else 19YY`. In other words, `if substr($1,1,2) >= 00 then print "20"substr($1,1,2), else print "19"substr($1,1,2)` – Kay Jul 04 '20 at 05:00
  • @Kay, ok so you mean from `00` to till current year it should be 20 added and rest of the years it should be `19` right? Kindly confirm on same once. – RavinderSingh13 Jul 04 '20 at 09:49
2

With GNU awk:

awk -v OFS="  " '
    function totime(t,     c, y, m, d, h) {
        y = substr(t, 1 ,2)
        m = substr(t, 3, 2)
        d = substr(t, 5, 2)
        h = substr(t, 7, 2)
        c = y >= 69 ? 19 : 20   # GNU date treats years 69-99 as 19xx else 20xx
        return mktime(c y " " m " " d " " h " 0 0")
    }
    function transformTime(t) {
        return strftime("%HH%d%b%Y", totime(t))
    }
    {
        $1 = transformTime($1)
        print
    }
' ifile.txt
03H06Aug1983  55  72
07H06Sep1987  83  87
12H06Jan1988  82  44
03H06Aug1989  55  72
07H06Nov2000  83  87
12H06Mar2001  82  44
18H06Dec2005  84  44

Or, Perl

perl -MTime::Piece -lane '
    $F[0] = Time::Piece->strptime($F[0], "%y%m%d%H")->strftime("%HH%d%b%Y");
    print join("  ", @F);
' ifile.txt
glenn jackman
  • 238,783
  • 38
  • 220
  • 352
1
{
    for (i=0; i<4; i++) {
        t[i] = substr($1, 2*i+1, 2);
    }
    d = t[0]"-"t[1]"-"t[2]" "t[3]":00";
    cmd = "date --date='"d"' +%HH%d%b%Y";
    cmd | getline $1;
    close(cmd);
    print
}

Save the above as script.awk and run as awk -f script.awk ifile.txt. It uses the date command for date format conversion.

pii_ke
  • 2,811
  • 2
  • 20
  • 30
  • You should mention that requires GNU awk for `gensub()`. Since you're using GNU awk, though, you don't need to call an external `date` as GNU awk has it's own time functions, and that's not a safe way to call `getline`, see http://awk.freeshell.org/AllAboutGetline. – Ed Morton Jul 04 '20 at 14:12
  • Thank you @Ed. I did not know that. I removed `gensub()`. I also read your article on `getline`, but I could not find a better way to read on line from a pipe. – pii_ke Jul 04 '20 at 15:27
  • The correct syntax would be `if ( (cmd | getline line) > 0 ) $1=line`. – Ed Morton Jul 04 '20 at 16:33
1

Using any awk in any shell on every UNIX box:

$ cat tst.awk
BEGIN {
    split("Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec",mths)
}
{
    for (i=1; i<length($1); i+=2) {
        t[(i-1)/2+1] = substr($1,i,2)
    }
    $1 = t[4] "H" t[3] mths[t[2]+0] "19" t[1]
    print
}

.

$ awk -f tst.awk file
03H06Aug1983 55 72
07H06Sep1987 83 87
12H06Jan1988 82 44
03H06Aug1989 55 72
07H06Nov1900 83 87
12H06Mar1901 82 44
18H06Dec1905 84 44
Ed Morton
  • 188,023
  • 17
  • 78
  • 185