Search code examples
shelldatesedgnu

replacing timestamp with date using sed


When using SED to replace timestamps with human readable dates the timestamp is always replaced with the epoch date plus the value placed after"\"

I have this working with Perl example but prefer to use sed. I have tried varying escape sequences and quoting "'` etc.

sed -re "s/([0-9]{10})/$(date -d @\1)/g" mac.txt

input (one string):

834|task|3||1561834555|Ods|12015|info|Task HMI starting 837|task|3||1561834702|Nailsd|5041|info|Configured with engine 6000.8403 (/opt/NAI/LinuxShield/engine/lib/liblnxfv.so), dats 9297.0000 (/opt/NAI/LinuxShield/engine/dat), 197 extensions, 0 extra drivers 

Expect date conversion but results are:

834|task|3||Wed Dec 31 19:00:01 EST 1969|Ods|12015|info|Task HMI starting 837|task|3||Wed Dec 31 19:00:01 EST 1969|Nailsd|5041|info|Configured with engine 6000.8403 (/opt/NAI/LinuxShield/engine/lib/liblnxfv.so), dats 9297.0000 (/opt/NAI/LinuxShield/engine/dat), 197 extensions, 0 extra drivers 838|task.

basically: this is what is being called:

$(date -d @\1) instead of $(date -d @\1561834555)

Solution

  • sed never sees the $(date -d @\1) -- the shell has executed that command substitution before sed launches.

    You could something like this:

    sed -Ee 's/([0-9]{10})/$(date -d @\1)/g' -e 's/^/echo "/' -e 's/$/"/' mac.txt | sh
    

    (note the single quotes, preventing the shell from doing any expansions)

    However, it's much more sensible to use a language that has date facilities built-in. GNU awk:

    gawk -F '|' -v OFS='|' '{
        for (i=1; i<=NF; i++)
            if ($i ~ /^[0-9]{10}$/)
                $i = strftime("%c", $i)
        print
    }' mac.txt
    

    Perl will probably be installed:

    perl -MPOSIX=strftime -pe 's{\b(\d{10})\b}{ strftime("%c", localtime $1) }ge' mac.txt
    # or, this is more precise as it only substitutes *fields* that consist of a timestamp
    perl -MPOSIX=strftime -F'\|' -lape '$_ = join "|", map { s/^(\d{10})$/ strftime("%c", localtime $1) /ge; $_ } @F' mac.txt