Unix Shell - sed: s/// not an address?

This is Interesting: Free IT Magazines  
Home > Archive > Unix Shell > December 2007 > sed: s/// not an address?





You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

Author sed: s/// not an address?
Robert Latest

2007-12-20, 1:26 pm

Hello,

I'm kind of puzzled. I'm trying to look through a file, and when something
matches, I'd like to put a certain portion of the line in sed's hold space.

OK, here's what I want. Below is a snippet of "ps afx" output, and I need
the last SCREEN process ID before some command I'm interested in (in this
case, slrn).

----------------------------------------

5710 ? \_ SCREEN
5711 pts/17 \_ /bin/bash
5841 pts/17 \_ /bin/bash
5842 pts/17 \_ slrn

----------------------------------------

Here's my script so far:

------------
#!/bin/sh
ps afx | sed -nr "s/^ *([0-9]+) \\?.*SCREEN/\\1/h;/$1/{g;p}"
------------

But sed won't let me use the 'h' command after s///, and it says "Unknown
option to s". But why can I use, for instance, the p command but not h?

I could have written this in 30 seconds using perl, but I'm currently in a
stubborn sed phase. I don't understand all this address/command thing.

robert
Ed Morton

2007-12-20, 1:26 pm



On 12/20/2007 9:08 AM, Robert Latest wrote:
> Hello,
>
> I'm kind of puzzled. I'm trying to look through a file, and when something
> matches, I'd like to put a certain portion of the line in sed's hold space.
>
> OK, here's what I want. Below is a snippet of "ps afx" output, and I need
> the last SCREEN process ID before some command I'm interested in (in this
> case, slrn).
>
> ----------------------------------------
>
> 5710 ? \_ SCREEN
> 5711 pts/17 \_ /bin/bash
> 5841 pts/17 \_ /bin/bash
> 5842 pts/17 \_ slrn
>
> ----------------------------------------
>
> Here's my script so far:
>
> ------------
> #!/bin/sh
> ps afx | sed -nr "s/^ *([0-9]+) \\?.*SCREEN/\\1/h;/$1/{g;p}"
> ------------
>
> But sed won't let me use the 'h' command after s///, and it says "Unknown
> option to s". But why can I use, for instance, the p command but not h?
>
> I could have written this in 30 seconds using perl, but I'm currently in a
> stubborn sed phase. I don't understand all this address/command thing.
>


Take a deep breath and put it behind you. Don't try to use sed for anything
other than simple substitutions. If you don't want to or aren't allowed to use
perl, use awk or ruby or.... Assuming the ps afx output is as you posted above,
the awk script would be:

ps afx | awk '$NF=="SCREEN"{p=$1} $NF=="slrn"{print p}'

See, all nice and clear and sensible....

Ed.

Edward Rosten

2007-12-20, 1:26 pm

On Dec 20, 8:08 am, Robert Latest <boblat...@yahoo.com> wrote:

> ps afx | sed -nr "s/^ *([0-9]+) \\?.*SCREEN/\\1/h;/$1/{g;p}"
> ------------
>
> But sed won't let me use the 'h' command after s///, and it says "Unknown
> option to s". But why can I use, for instance, the p command but not h?


The s command is of this form:

s/pattern/replacement/flags

Note the flags at the end which control the usage (for instance "g"
makes it global, so it works on all instances on the current line, not
just the first). In other words, sed thinks that your "h" command is a
flag controlling the "s" command, and "h" isn't a valid flag. Try
inserting a semicolon:

sed -nr "s/^ *([0-9]+) \\?.*SCREEN/\\1/;h;/$1/{g;p}"


> I could have written this in 30 seconds using perl, but I'm currently in a
> stubborn sed phase. I don't understand all this address/command thing.


Good for you, sed is rather fun. It's worth leaarning since it's very
useful for oneliners, etc.

-Ed

Robert Latest

2007-12-21, 7:33 am

Edward Rosten wrote:

> The s command is of this form:
>
> s/pattern/replacement/flags
>
> Note the flags at the end which control the usage (for instance "g"
> makes it global, so it works on all instances on the current line, not
> just the first). In other words, sed thinks that your "h" command is a
> flag controlling the "s" command, and "h" isn't a valid flag. Try
> inserting a semicolon:


Yes, but 'p' is allowed at that point, and 'p' is a command after all.

> sed -nr "s/^ *([0-9]+) \\?.*SCREEN/\\1/;h;/$1/{g;p}"


But if I put a ; between the address and the command, how does sed know that
that command belongs to the address?

> Good for you, sed is rather fun. It's worth leaarning since it's very
> useful for oneliners, etc.


Yes, I've grown rather fond of the "find | sed | sh" approach for large
batches of files.

robert
Michael Tosch

2007-12-21, 7:33 am

Robert Latest wrote:
> Hello,
>
> I'm kind of puzzled. I'm trying to look through a file, and when something
> matches, I'd like to put a certain portion of the line in sed's hold space.
>
> OK, here's what I want. Below is a snippet of "ps afx" output, and I need
> the last SCREEN process ID before some command I'm interested in (in this
> case, slrn).
>
> ----------------------------------------
>
> 5710 ? \_ SCREEN
> 5711 pts/17 \_ /bin/bash
> 5841 pts/17 \_ /bin/bash
> 5842 pts/17 \_ slrn
>
> ----------------------------------------
>
> Here's my script so far:
>
> ------------
> #!/bin/sh
> ps afx | sed -nr "s/^ *([0-9]+) \\?.*SCREEN/\\1/h;/$1/{g;p}"
> ------------
>
> But sed won't let me use the 'h' command after s///, and it says "Unknown
> option to s". But why can I use, for instance, the p command but not h?
>
> I could have written this in 30 seconds using perl, but I'm currently in a
> stubborn sed phase. I don't understand all this address/command thing.
>
> robert



s/regexp/replacement/h
is syntax error: h is an unknown option to the s command.

s/regexp/replacement/;h
syntax correct, but h is unconditionally run.

You maybe want

/regexp/{s/regexp/replacement/;h;}

or

!s/regexp/replacement/;tL1
h
:L1
/$1/{g;p;}

Yes, better use PERL or awk here.


--
Michael Tosch @ hp : com
Stephane Chazelas

2007-12-21, 7:33 am

On Fri, 21 Dec 2007 13:55:46 +0100, Michael Tosch wrote:
[...]
> /regexp/{s/regexp/replacement/;h;}


or

/regexp/{s//replacement/;h;}

> or
>
> !s/regexp/replacement/;tL1


! is only run a command if the address range does *not* match.
You can't use it to negate the meaning of the "s" commands wrt
t.

> h
> :L1
> /$1/{g;p;}

[...]

Instead:

s/regexp/replacement/; t2
:1
/$1/{g;p;}
d
:2
h
b1

--
Stephane
Michael Tosch

2007-12-21, 1:25 pm

Stephane Chazelas wrote:
> On Fri, 21 Dec 2007 13:55:46 +0100, Michael Tosch wrote:
> [...]
>
> or
>
> /regexp/{s//replacement/;h;}
>
>
> ! is only run a command if the address range does *not* match.
> You can't use it to negate the meaning of the "s" commands wrt
> t.
>
> [...]
>
> Instead:
>
> s/regexp/replacement/; t2
> :1
> /$1/{g;p;}
> d
> :2
> h
> b1
>


Then, at least,
one should omit the d (or n) command:

s/regexp/replacement/; t1
b2
:1
h
:2
/$1/{g;p;}


--
Michael Tosch @ hp : com
Rakesh Sharma

2007-12-24, 7:33 am

Try this :

sed -ne '
/SCREEN/{
s/ .*//;h;d
}
/slrn/{g;p;}
'




On Dec 20, 8:08 pm, Robert Latest <boblat...@yahoo.com> wrote:
> Hello,
>
> I'm kind of puzzled. I'm trying to look through a file, and when something
> matches, I'd like to put a certain portion of the line in sed's hold space.
>
> OK, here's what I want. Below is a snippet of "ps afx" output, and I need
> the last SCREEN process ID before some command I'm interested in (in this
> case, slrn).
>
> ----------------------------------------
>
> 5710 ? \_ SCREEN
> 5711 pts/17 \_ /bin/bash
> 5841 pts/17 \_ /bin/bash
> 5842 pts/17 \_ slrn
>
> ----------------------------------------

Edward Rosten

2007-12-24, 7:19 pm

Robert Latest wrote:
> Edward Rosten wrote:
>
>
> Yes, but 'p' is allowed at that point, and 'p' is a command after all.


Yes, but p is also a valid option to s. The fact that they have the
same name is coincidence.


>
> But if I put a ; between the address and the command, how does sed know that
> that command belongs to the address?


It doesn't. Use /blah/{command1;etc;}

> Yes, I've grown rather fond of the "find | sed | sh" approach for large
> batches of files.


Very useful. See my programs parallel and ssh_parallel here:
http://mi.eng.cam.ac.uk/~er258/code/index.html
for use with this kind of construct.

-Ed
-
(You can't go wrong with psycho-rats.)(http://mi.eng.cam.ac.uk/~er258)

/d{def}def/f{/Times s selectfont}d/s{11}d/r{roll}d f 2/m {moveto}d -1
r 230 350 m 0 1 179{1 index show 88 rotate 4 mul 0 rmoveto}for/s 12 d
f pop 235 420 translate 0 0 moveto 1 2 scale show showpage
Sponsored Links






Free braindumps | Software forum | Database administration forum

Copyright 2003 - 2009 webservertalk.com