Text Processing Sed – Replace Epoch Timestamps with Other Formats

datesedtext processing

I have a file that contains epoch dates which I need converting to human-readable. I already know how to do the date conversion, eg:

[server01 ~]$ date -d@1472200700
Fri 26 Aug 09:38:20 BST 2016

..but I'm struggling to figure out how to get sed to walk through the file and convert all the entries.
The file format looks like this:

#1472047795
ll /data/holding/email
#1472047906
cat /etc/rsyslog.conf
#1472048038
ll /data/holding/web

Best Answer

Assuming consistent file format, with bash you can read the file line by line, test if it's in given format and then do the conversion:

while IFS= read -r i; do [[ $i =~ ^#([0-9]{10})$ ]] && \
      date -d@"${BASH_REMATCH[1]}"; done <file.txt

BASH_REMATCH is an array whose first element is the first captured group in Regex matching, =~, in this case the epoch.


If you want to keep the file structure:

while IFS= read -r i; do if [[ $i =~ ^#([0-9]{10})$ ]]; then printf '#%s\n' \
   "$(date -d@"${BASH_REMATCH[1]}")"; else printf '%s\n' "$i"; fi; done <file.txt

this will output the modified contents to STDOUT, to save it in a file e.g. out.txt:

while ...; do ...; done >out.txt

Now if you wish, you can replace the original file:

mv out.txt file.txt

Example:

$ cat file.txt
#1472047795
ll /data/holding/email
#1472047906
cat /etc/rsyslog.conf
#1472048038
ll /data/holding/web

$ while IFS= read -r i; do [[ $i =~ ^#([0-9]{10})$ ]] && date -d@"${BASH_REMATCH[1]}"; done <file.txt
Wed Aug 24 20:09:55 BDT 2016
Wed Aug 24 20:11:46 BDT 2016
Wed Aug 24 20:13:58 BDT 2016

$ while IFS= read -r i; do if [[ $i =~ ^#([0-9]{10})$ ]]; then printf '#%s\n' "$(date -d@"${BASH_REMATCH[1]}")"; else printf '%s\n' "$i"; fi; done <file.txt
#Wed Aug 24 20:09:55 BDT 2016
ll /data/holding/email
#Wed Aug 24 20:11:46 BDT 2016
cat /etc/rsyslog.conf
#Wed Aug 24 20:13:58 BDT 2016
ll /data/holding/web
Related Question