|
|
|
|
||||||
| comp.unix.shell Using and programming the Unix shell. |
![]() |
|
|
LinkBack | Outils de la discussion |
|
|
#1 |
|
Messages: n/a
Hébergeur: |
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 }"------------ 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 |
|
|
|
#2 |
|
Messages: n/a
Hébergeur: |
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 }"> ------------ > > 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. |
|
|
|
#3 |
|
Messages: n/a
Hébergeur: |
On Dec 20, 8:08 am, Robert Latest <boblat...@yahoo.com> wrote:
> ps afx | sed -nr "s/^ *([0-9]+) \\?.*SCREEN/\\1/h;/$1/{g }"> ------------ > > 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 }"> 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 |
|
|
|
#4 |
|
Messages: n/a
Hébergeur: |
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 }"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 |
|
|
|
#5 |
|
Messages: n/a
Hébergeur: |
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 }"> ------------ > > 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 ;}Yes, better use perl or awk here. -- Michael Tosch @ hp : com |
|
|
|
#6 |
|
Messages: n/a
Hébergeur: |
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 ;}[...] Instead: s/regexp/replacement/; t2 :1 /$1/{g ;}d :2 h b1 -- Stephane |
|
|
|
#7 |
|
Messages: n/a
Hébergeur: |
Stephane Chazelas wrote:
> 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 ;}> [...] > > Instead: > > s/regexp/replacement/; t2 > :1 > /$1/{g ;}> 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 ;}-- Michael Tosch @ hp : com |
|
|
|
#8 |
|
Messages: n/a
Hébergeur: |
Try this :
sed -ne ' /SCREEN/{ s/ .*//;h;d } /slrn/{g ;}' 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 > > ---------------------------------------- |
|
![]() |
| Outils de la discussion | |
|
|