Link to home
Start Free TrialLog in
Avatar of FFT
FFT

asked on

Apply an external function to a SED backreference

Hello,

I have a small shell script I intend to use to replace time stamps from a log file with readables dates :

1111054703 ConnStartListen starting thread ConnStartListen for 127.0.0.1
1111054703 iplud bound to address 0.0.0.0
1111054703 ipludAddMembership adding membership for 0.0.0.0

to

jeu 17 mars 2005 - 01:00:01 ConnStartListen starting thread ConnStartListen for 127.0.0.1
jeu 17 mars 2005 - 01:02:01 iplud bound to address 0.0.0.0
jeu 17 mars 2005 - 01:03:01 ipludAddMembership adding membership for 0.0.0.0

here's the script
-----------------------------
#!/bin/sh

#the date_time stamp functions returns a french date like "jeu 17 mars 2005 - 01:00:01" from a time stamp when called
date_timestamp()
 {
   date -u --date "Jan 1, 1970 00:00:00 -0100 + $1 seconds" | sed 's/ UTC//' | awk '{print $1" "$3" "$2" "$5" - "$4}'
 }

                                                             #date_timestamp \1 does not work below
tail /var/log/my.log | sed "s/\(^[0-9]*\):/`(date_timestamp \1)`/g"

exit 0
-----------------------------

The problem is that the last sed expression sends the first back reference \1 litteraly to the date_time function and not its value so the date_timestamp function receives \1 instead of 1111054709 for example.

So i just get

jeu 1 jan 1970 - 01:00:01 ConnStartListen: starting thread ConnStartListen for 195.137.248.170:0
jeu 1 jan 1970 - 01:00:01 connAccept: close(socket) failed with error 9
jeu 1 jan 1970 - 01:00:01 Retrospect Client Terminated.

Any clue to fix this ?

I might precise that many of you would will indicate me to use perl for this kind of stuff... but I intend to do this using shell script only just for the pleasure of knowledge ;-)

So the solution MUST use shell commands only ;-)

thanks for your help

ASKER CERTIFIED SOLUTION
Avatar of sunnycoder
sunnycoder
Flag of India image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
perl -MPOSIX -lane '$F[0]=strftime("%D %T",localtime($F[0])); print join(" ",@F)' yourfile
# feel free to improve the format of strftime ;-)
Avatar of FFT
FFT

ASKER

Ok sunnycoder, it worked fine thanks very much !

for the record the "true" working script is as follow :
--------------------------------
#!/bin/sh

date_timestamp()
{
      date -u --date "Jan 1, 1970 00:00:00 -0100 + $1 seconds" | sed 's/ UTC//' | awk '{print $1" "$3" "$2" "$5" - "$4}'
}

tail /var/log/my.log | while read line
do
      pre=`echo $line | sed 's/\(^[0-9]*\).*/\1/'`
      post=`date_timestamp $pre`
      echo $line | sed "s/^[0-9]*/$post/"
done

exit 0
--------------------------------
PS : thanks to ahoffmann but I asked it to be in pure shell with no perl ;-)
> .. pure shell ..
sed, date, awk, tail is as "pure" as perl
;-)