Operating System - HP-UX
1832331 Members
3051 Online
110041 Solutions
New Discussion

Using sed instead of cut utility

 
Danny Fang
Frequent Advisor

Using sed instead of cut utility

Hi,

I have a UNIX shell script which is to extract the timestamp values into their separate components such as the year, month, day, hour, min, secs.

The timestamp is denoted by the variable $timestamp below. The $timestamp denotes the UNIX epoch time since 1970.

timestamp=1159445287
From the $timestamp value, I've converted the UNIX timestamp into a format of year, month, day, hour, min, seconds into the variable
$newTimeToSecs.
newTimeToSecs=060922113366

Now, I'm attempting to extract values of the year, month, day, hour, min, seconds from the
variable "$newTimeToSecs" and place them into separate variables. I've used the 'cut' utility to extract them.

year=`/usr/bin/echo $newTimeToSecs |/usr/bin/cut -b1-2`
month=`/usr/bin/echo $newTimeToSecs |/usr/bin/cut -b3-4`
day=`/usr/bin/echo $newTimeToSecs |/usr/bin/cut -b5-6`
hour=`/usr/bin/echo $newTimeToSecs |/usr/bin/cut -b7-8`
MIN=`/usr/bin/echo $newTimeToSecs |/usr/bin/cut -b9-10`
secs=`/usr/bin/echo $newTimeToSecs |/usr/bin/cut -b11-12`

However, I'd would like to know how I could used the 'sed' utility to perform the same task.

year=`echo newTimeToSecs | sed -e 's/\([0-9]\{2\}\)\([0-9]\{2\}\)\([0-9]\{2\}\)\([0-9]\{2\}\)\([0-9]\{2\}\)\([0-9]\{2\}\)/\1/'`

month=`echo newTimeToSecs | sed -e 's/\([0-9]\{2\}\)\([0-9]\{2\}\)\([0-9]\{2\}\)\([0-9]\{2\}\)\([0-9]\{2\}\)\([0-9]\{2\}\)/\2/'`

day=`echo newTimeToSecs | sed -e 's/\([0-9]\{2\}\)\([0-9]\{2\}\)\([0-9]\{2\}\)\([0-9]\{2\}\)\([0-9]\{2\}\)\([0-9]\{2\}\)/\3/'`

hour=`echo newTimeToSecs | sed -e 's/\([0-9]\{2\}\)\([0-9]\{2\}\)\([0-9]\{2\}\)\([0-9]\{2\}\)\([0-9]\{2\}\)\([0-9]\{2\}\)/\4/'`

min=`echo newTimeToSecs | sed -e 's/\([0-9]\{2\}\)\([0-9]\{2\}\)\([0-9]\{2\}\)\([0-9]\{2\}\)\([0-9]\{2\}\)\([0-9]\{2\}\)/\5/'`

seconds=`echo newTimeToSecs | sed -e 's/\([0-9]\{2\}\)\([0-9]\{2\}\)\([0-9]\{2\}\)\([0-9]\{2\}\)\([0-9]\{2\}\)\([0-9]\{2\}\)/\6/'`

Could anyone show me a better way using 'sed' to achieve the same task?

Thanks



12 REPLIES 12
Jonathan Fife
Honored Contributor

Re: Using sed instead of cut utility

There's no way for sed to assign multiple variables at once, so you're probably better off going with cut for readability. If you have your heart bent on using sed I would eliminate all the pattern string after the text you're looking for -- eg.

year=$(echo $newTimeToSecs | sed -e 's/^\([0-9]\{2\}\).*/\1/')
month=$(echo $newTimeToSecs | sed -e 's/[0-9]\{2\}\([0-9]\{2\}\).*/\1/')
etc.
Decay is inherent in all compounded things. Strive on with diligence
James R. Ferguson
Acclaimed Contributor

Re: Using sed instead of cut utility

Hi:

For something like this, I'd use Perl or 'awk'. With Perl you could 'unpack' or use 'substr' to perform the extractions. With 'awk' you have 'substr'.

Otherwise, my choice would be to use 'cut'. It is the most natural corrollary.

Regards!

...JRF...
Peter Godron
Honored Contributor

Re: Using sed instead of cut utility

Danny,
last few lines of section 36.23.4 in http://www.sm.luth.se/~alapaa/file_fetch/unixcdbookshelf/upt/ch36_23.htm seems to suggest you could assign values to multiple variables in one go, with eval.

I have never used this method.

I tend to choose the easiest path to a solution, which in this case seems to be cut.
Peter Nikitka
Honored Contributor

Re: Using sed instead of cut utility

Hi,

what about

echo $newTimeToSecs | sed 's/\(..\)/\1 /g' | read year month day hour min seconds

This will not work in a (Linux-)Pdksh or bash, but in the HP-Posix shell and other KSHs.

mfG Peter
The Universe is a pretty big place, it's bigger than anything anyone has ever dreamed of before. So if it's just us, seems like an awful waste of space, right? Jodie Foster in "Contact"
OldSchool
Honored Contributor

Re: Using sed instead of cut utility

the easy way is:

date +'%y %m %d %H %M %S' | read yr mo da hr mn sec

change %H to %I for 12hr clock
OldSchool
Honored Contributor

Re: Using sed instead of cut utility

disregard the previous. i didn't note that you weren't creating the stamps, but working w/ existing....more coffed please
Sandman!
Honored Contributor

Re: Using sed instead of cut utility

How about the following:

year=`echo $newTimeToSecs | sed 's/^\(.\{2\}\).*$/\1/p'`
month=`echo $newTimeToSecs | sed 's/^..\(.\{2\}\).*$/\1/p'`
day=`echo $newTimeToSecs | sed 's/^....\(.\{2\}\).*$/\1/p'`
hour=`echo $newTimeToSecs | sed 's/^.\{6\}\(.\{2\}\).*$/\1/p'`
min=`echo $newTimeToSecs | sed 's/^.\{8\}\(.\{2\}\).*$/\1/p'`
seconds=`echo $newTimeToSecs | sed 's/^.\{10\}\(.\{2\}\)$/\1/p'`
Arturo Galbiati
Esteemed Contributor

Re: Using sed instead of cut utility

Hi,
on my Hp-UX 11i:
% newTimeToSecs=060922113366
%>echo $newTimeToSecs | sed 's/\(..\)/\1 /g' | read yy mm dd hh mm ss
% echo $yy $mm $dd $hh $mm $ss

HTH,
Art
Danny Fang
Frequent Advisor

Re: Using sed instead of cut utility

HI Sandman,

I attempted your suggested method but I noticed it duplicated the values being output.

mz$ echo 1159528031 | sed 's/^..\(.\{2\}\).*$/\1/p'
59
59
mz$ echo 1159528031 |sed 's/^....\(.\{2\}\).*$/\1/p'
52
52
mz$ echo 1159528031 |sed 's/^.\{6\}\(.\{2\}\).*$/\1/p'
80
80
mz$ echo 1159528031 |sed 's/^\(.\{2\}\).*$/\1/p'
11
11
mz$ echo 1159528031|sed 's/^.\{8\}\(.\{2\}\).*$/\1/p'
31
31

Could you point out where did I go wrong?

Thanks
Danny
Peter Nikitka
Honored Contributor

Re: Using sed instead of cut utility

Hi,

did you try my solution?

mfG Peter
The Universe is a pretty big place, it's bigger than anything anyone has ever dreamed of before. So if it's just us, seems like an awful waste of space, right? Jodie Foster in "Contact"
Sandman!
Honored Contributor

Re: Using sed instead of cut utility

>HI Sandman,

>I attempted your suggested method but I noticed it duplicated the values being >output.

>mz$ echo 1159528031 | sed 's/^..\(.\{2\}\).*$/\1/p'
>59
>59

Provide the "-n" switch to all the sed commands for removing duplicates i.e.

mz$ echo 1159528031 | sed -n 's/^..\(.\{2\}\).*$/\1/p'
Peter Nikitka
Honored Contributor

Re: Using sed instead of cut utility

Hi,

in Sandmans solution you can just drop the 'p(rint)' directive AND the '-n' option:
Use
echo 1159528031 | sed 's/^..\(.\{2\}\).*$/\1/'
59

mfG Peter
The Universe is a pretty big place, it's bigger than anything anyone has ever dreamed of before. So if it's just us, seems like an awful waste of space, right? Jodie Foster in "Contact"