0

I have a file with following enteries

Nov 29 15:15 ,alert_logevent
Nov 29 15:15 ,alert_webhook
Nov 29 15:15 ,appsbrowser
Oct 20 2017 ,ClearPassOnSplunk_2
Oct 10 2017 ,Dnslookup
Oct 12 2017 ,domainCategories

I want to convert date time to YYYYMMDDHHMMSS with out using loops some thing like this

 cat SOMEFILE_WITH_DATE_AND_DATE | awk '{print "date -d \""$1, $2, $3"\"" " +" "%Y%m%d%H%M%S" , $4 }'

I want the output to look like this

20181129151500,alert_logevent
20181129151500,alert_webhook
20181129151500,appsbrowser
20181129151500,appsbrowser

and so forth

I tried system () function in awk but it does not accept more than 1 argument.

3
  • 1
    How are you coming up with HH MM and SS for “Oct 12 2018”?
    – Jeff Schaller
    May 1, 2018 at 20:13
  • Don't cat file | awk 'stuff'; that's a Useless Use of cat. Instead, awk 'stuff' file.
    – DopeGhoti
    May 1, 2018 at 20:14
  • 1
    About system() in awk, unix.stackexchange.com/a/344855/14831 might be useful.
    – njsg
    May 1, 2018 at 20:18

3 Answers 3

2

Not sure how your expected output relates to your input. I would suggest:

$ perl -MPOSIX -MDate::Parse -pe 's{[^,]*}{
   strftime("%Y%m%d%H%M%S", localtime str2time($&))}e' <your-file
20171129151500,alert_logevent
20171129151500,alert_webhook
20171129151500,appsbrowser
20171020000000,ClearPassOnSplunk_2
20171010000000,Dnslookup
20171012000000,domainCategories

To use GNU date's ability to parse those dates, and avoid running one date invocation per line, you could do (assuming a shell with support for ksh-style process-substitution (like ksh, bash or zsh)):

paste -d , <(<yourfile cut -d , -f1 | date -f- +%Y%m%d%H%M%S) \
           <(<yourfile cut -d , -f2-)

Note however that it gives:

20181129151500,alert_logevent
20181129151500,alert_webhook
20181129151500,appsbrowser
20171020000000,ClearPassOnSplunk_2
20171010000000,Dnslookup
20171012000000,domainCategories

Though it's what you asked, it sounds unlikely that it is what you want as those Nov 29 15:15 sound more likely to be timestamps from 2017 (last year) than some in the future.

Here, it looks like those dates are as reported by ls -l in the POSIX locale. So portably, you could adapt that function from another Q&A to convert it to a more useful format. Or better, use a better way than ls -l to store file dates in the file in the first place (like GNU find -printf or GNU date -r or zsh stat, or GNU/BSD stat or ast ls --format...) where you can use a more useful, precise and unambiguous format.

0

If zero 000000 is ok as HHMMSS for entries without time data, use the following awk approach:

awk 'BEGIN{ FS = OFS = "," }
     { 
         cmd = "date -d\042" $1 "\042 +%Y%m%d%H%M%S";
         cmd | getline d; close(cmd);
         print d, $2
     }' file

The output:

20181129151500,alert_logevent
20181129151500,alert_webhook
20181129151500,appsbrowser
20171020000000,ClearPassOnSplunk_2
20171010000000,Dnslookup
20171012000000,domainCategories
0
0

Requires GNU awk for the builtin time functions

gawk -F, -v OFS=, '
    BEGIN {
        # assumes english month names
        split("Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec", m, ",")
        for (idx in m) months[m[idx]] = idx
        delete m
    }
    function date2timestamp(datestamp,    tmp,now,timestamp,year,hour,minute) {
        now = systime()
        split(datestamp, tmp, " ")
        if (tmp[3] ~ /:/) {
            year = strftime("%Y", now)
            hour = substr(tmp[3], 1, 2)
            minute = substr(tmp[3], 4, 2)
        }
        else {
            year = tmp[3]
            hour = minute = 0
        }
        timestamp = mktime(year " " months[tmp[1]] " " tmp[2] " " hour " " minute " 0")
        if (timestamp > now)
            timestamp = mktime((year-1) " " months[tmp[1]] " " tmp[2] " " hour " " minute " 0")
        return strftime("%Y%m%d%H%M00", timestamp)
    }
    {
        $1 = date2timestamp($1)
        print
    }
' file

output

20171129151500,alert_logevent
20171129151500,alert_webhook
20171129151500,appsbrowser
20171020000000,ClearPassOnSplunk_2
20171010000000,Dnslookup
20171012000000,domainCategories

Your input file looks like the result of parsing ls -l. You might want to skip that file and do something like

stat -c '%Y,%n' * | gawk -F, -v OFS=, '{$1 = strftime("%Y%m%d%H%M%S", $1)}1'

This isn't safe (in the sense of handling filenames with newlines) but it will give you the accurate file mtime.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .