1

I have a file which contain multiple rows. Some rows represent date and time but that time is in Epoch format. I have tried using some command but that command converted all of the numeric digits. I want to convert only what is applicable. Same file is as below :-

cat FORMATTED 
=============================================================
0='917598936722' 395='1529313008' 391='0' 165='0' 142='0' 131='Status_Pending'
=============================================================

0='917598936722'    :MSISDN  
131='Status_Pending':PROMO_TP3_STATUS  
142='0'             :USAGE_COUNT_3_STATUS  
165='0'             :EBUCKET_USAGE_TS_3  
391='0'             :PROM_3_END_TIMESTAMP  
395='1529313008'    :Date_TC1  
396=='1529313008'   :TC2

I need to convert the epoch time present in rows Date_TC1 and TC2. Similar to this there are many more rows and I don't which row represent Epoch date/time; but where this date/time is present in Epoch format, I need to convert to human readable format.

  • 1
    Strictly speaking, a timestamp in Unix epoch format is just an integer. There is no way to say "this integer is not a timestamp" unless you give restrictions on the value of the integer (such as "it has to be 1500000000 or larger (after July 14, 2017, 02:40 UTC)". – Kusalananda Aug 9 '18 at 11:49
1
cat conv.awk

/Date_TC1/||/TC2/   {
    split($0, r, "'")
    print(r[1], strftime("%c", r[2]), r[3], r[4])
    next
    }

{ print }

awk -f conv.awk src.txt
=============================================================
0='917598936722' 395='1529313008' 391='0' 165='0' 142='0' 131='Status_Pending'
=============================================================

0='917598936722'    :MSISDN  
131='Status_Pending':PROMO_TP3_STATUS  
142='0'             :USAGE_COUNT_3_STATUS  
165='0'             :EBUCKET_USAGE_TS_3  
391='0'             :PROM_3_END_TIMESTAMP  
395= Mon 18 Jun 2018 11:10:08 AM CEST     :Date_TC1   
396== Mon 18 Jun 2018 11:10:08 AM CEST    :TC2 
  • 2
    Since the question doesn't specify Linux or a GNU environment, I'll just point out that strftime in awk is a GNU extension to the standard awk – Jeff Schaller Aug 9 '18 at 12:45
0

Using GNU sed, try this:

sed -re 's/([0-1][0-6][0-9]{8})/$(date -d @&)/g;
         /date -d/ s/\x27/\\\x27/g;
         /date -d/ s/\$[^(]/\\$\(/g;
         /date -d/ s/.*/echo &/e' FORMATTED

Explanation:

  • s/([0-1][0-6][0-9]{8})/$(date -d @&)/g: Replace all timestamps (10 digits with 00 - 16 as first numbers) with $(date -d @<timestamp>)

  • /date -d/: Only run the following commands when date -d was found in the line (= lines that we changed in the previous step)

  • s/\x27/\\\x27/g: Replace all ' with \' so that everything in between will be interpreted in the last step.

  • s/\$[^(]/\\$\(/g;: Replace all $ that are not followed by a ( with \$, so that these will not be interpreted as variable in the last step

  • s/.*/echo &/;e: Execute (e) an echo on the whole line (.*)

Note: This behaves similar to eval, executing everything that is in the original file, e.g. `do_something_evil`.

(via)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.