Skip to content
Advertisement

Convert nth column of CSV from EPOCH to human readable in bash

I’ve tried to create a single line command to convert a particular column in a CSV from EPOCH to human readable. The file contains various columns, depending on the particular file. E.g. in this file EPOCH is in column 3 of 3, in another file it is in column 5 of 9.

[user@Dreadnaught log]$ cat FailedApps.log
Config, Unable to open file /var/config/snapshot.xml, 1658872997
Config, Unable to open file /var/config/snapshot.xml, 1661421388
Config, Unable to open file /var/config/snapshot.xml, 1661421414

The basic conversion works when done manually, so I know the values are valid EPOCH dates:

[user@Dreadnaught log]$ date -d@1658872997
Tue Jul 26 22:03:17 UTC 2022

But I’m having trouble passing item 3 to the date function correctly when I parse the file – it appears the EPOCH date gets passed with a space in front of it, which breaks the date command. Here’s my attempt, learnt from other posts on this forum:

[user@Dreadnaught log]$ cat FailedApps.log | awk -F, '{ OFS = FS; command="date -d@""$3"""; command |getline; close(command); print}'
date: invalid date '@ 1658872997'
Config, Unable to open file /var/config/snapshot.xml, 1658872997
date: invalid date '@ 1661421388'
Config, Unable to open file /var/config/snapshot.xml, 1661421388
date: invalid date '@ 1661421414'
Config, Unable to open file /var/config/snapshot.xml, 1661421414

Please let me know how to correctly pass $3 to the date function? I tried a sed but that made it worse.

Note: strftime is not available in this build, and it’s an embedded machine so I can’t add it.

Advertisement

Answer

Your fields are separated by , rather than , inform your awk about that inside BEGIN and then date should start working:

awk 'BEGIN{FS=OFS=", "}{command="date -d@""$3"""; command |getline; close(command); print}' FailedApps.log

Observe that also you do not have to use cat as awk can read files on its’ own.

That is reading the 3rd column and converting it correctly, but it’s not printing the first two columns.

You might use separate printf for that as follows

awk 'BEGIN{FS=OFS=", "}{printf "%s%s%s%s",$1,OFS,$2,OFS}{command="date -d@""$3"""; command |getline; close(command); print}' FailedApps.log

Be warned that above code assumes input file with 3rd column, in order to make it work with variable number of fields you might use for loop which will printf each but last field followed by OFS

User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement