SherpaPsy
SherpaPsy

Reputation: 73

convert month from Aaa to xx in little script with awk

I am trying to report on the number of files created on each date. I can do that with this little one liner:

ls -la foo*.bar|awk '{print $7, $6}'|sort|uniq -c

and I get a list how many fooxxx.bar files were created by date, but the month is in the form: Aaa (ie: Apr) and I want xx (ie: 04).

I have feeling the answer is in here:

awk '
BEGIN{
   m=split("Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec",d,"|")
   for(o=1;o<=m;o++){
      months[d[o]]=sprintf("%02d",o)
    }
format = "%m/%d/%Y %H:%M"
}
{
split($4,time,":")
date = (strftime("%Y") " " months[$2] " " $3 " " time[1] " " time[2] " 0")
print strftime(format, mktime(date))
}'

But have no to little idea what I need to strip out and no idea how to pass $7 to whatever I carve out of this to convert Apr to 04.

Thanks!

Upvotes: 5

Views: 5847

Answers (5)

Ed Morton
Ed Morton

Reputation: 204229

Here's the idiomatic way to convert an abbreviated month name to a number in awk:

$ echo "Feb" | awk '{printf "%02d\n",(index("JanFebMarAprMayJunJulAugSepOctNovDec",$0)+2)/3}'
02

$ echo "May" | awk '{printf "%02d\n",(index("JanFebMarAprMayJunJulAugSepOctNovDec",$0)+2)/3}'
05

Let us know if you need more info to solve your problem.

Upvotes: 23

Olivier Dulac
Olivier Dulac

Reputation: 3791

Adding a version for AIX, that shows how to retrieve all the date elements (in whatever timezone you need it them in), and display an iso8601 output

tempTZ="UTC" ; TZ="$tempTZ" istat /path/to/somefile \
| grep modified \
| awk -v tmpTZ="$tempTZ" '
   BEGIN {Mmms="Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec"; 
          n=split(Mmms,Mmm," ") ; 
          for(i=1;i<=n;i++){ mm[Mmm[i]]=sprintf("%02d",i) } 
   }
         { printf("%s-%s-%sT%s %s",$NF, mm[$4], $5, $6, tmpTZ )  }
  ' ## this will output an iso8601 date of the modification date of that file, 
    ## for ex: 2019-04-18T14:16:05 UTC 
 ## you can tempTZ=anything, for ex: tempTZ="UTC+2" to see that date in UTC+2 timezone... or tempTZ="EST" , etc

I show the iso8601 version to make it more known & used, but of course you may only need the "mm" portion, which is easly done : mm[$4]

Upvotes: 0

Achim Haag
Achim Haag

Reputation: 1

To parse AIX istat, I use:

istat .profile | grep "^Last modified" | read dummy dummy dummy  mon day time dummy yr dummy
echo "M: $mon D: $day T: $time Y: $yr"
-> Month: Mar Day: 12 Time: 12:05:36 Year: 2012

To parse AIX istat month, I use this two-liner AIX 6.1 ksh 88:

monstr="???JanFebMarAprMayJunJulAugSepOctNovDec???"
mon="Oct" ; hugo=${monstr%${mon}*} ; hugolen=${#hugo} ; let hugol=hugolen/3 ; echo "Month: $hugol"
-> Month: 10

1..12 : month name ok

If lt 1 or gt 12 : month name not ok

Instead of "hugo" use speaking names ;-))

Upvotes: 0

tommy.carstensen
tommy.carstensen

Reputation: 9622

Assuming the name of the months only appear in the month column, then you could do this:

ls -la foo*.bar|awk '{sub(/Jan/,"01");sub(/Feb/,"02");print $7, $6}'|sort|uniq -c

Upvotes: 1

Dennis Williamson
Dennis Williamson

Reputation: 360425

Just use the field number of your month as an index into the months array.

print months[$6]

Since ls output differs from system to system and sometimes on the same system depending on file age and you didn't give any examples, I have no way of knowing how to guide you further.

Oh, and don't parse ls.

Upvotes: 0

Related Questions