Need Help with a sed command involving Regex

Hi,
Iam a newbie to SED. I'm faced with a problem as described.

Given the file with text

1  rwerwerwe rere                         
2  fdfefefe fsdfds                        
3  rerere ffff trtrt                      
4  aaaa 1234 asadsdsd                     
5  hfjfjfjsjfsf shfshfsjhshs              
6  dssssdsdsdd                            
7  dsgdshgsdgdsdgssgdsgdsdhsgdshgshdshdg  
8  kjjkjkj         0---+---0              
9  gfhdfgdfhfgdhhfgdhfgd                  
10 sgdhsgdhsdgsdhgsdgsdhhdg               
11 1234hjhhh ghgsggdgdg                   
12 dddhhdjdhdh                            
13 dagdhdgahadgadg  0---0---+             

I want to output two lines , line no 8 and line no 4 .The condition being the first occurrence of 0- or -0 and then the looking back and selecting the line with 1234.
So the two lines out put would be

aaaa 1234 asadsdsd  
kjjkjkj         0---+---0                   

Rgds
SShinde

You may try awk approach

$ awk '/1234/{p=$0;X=NR}/0\-|\-0/ && NR-X == 4{print p RS $0}' file
aaaa 1234 asadsdsd
kjjkjkj 0---+---0

OR

$ tac file| awk '/0\-|\-0/{p=$0;X=NR}/1234/ && NR - X == 4{print p RS $0}' | tac
aaaa 1234 asadsdsd
kjjkjkj 0---+---0

Hi,
@SShinde: Why lines 11 and 13 don't work ?

Regards.

Hi Akshay,
Works like a charm on the text snippet that I had attached earlier.
Somehow it is not working on the text snippet that I'm working on :-

Snippet starts :-

-------------------------------------------------
               Load step no.                          =     1                       
               Load increment scaled to                                             
               maximum load level                                                   
                                                                                    
               Load increment                         =    1.000                    
               New load level                         =    1.000                    
               Current stiffness parameter            =    1.000                    
               Solution accuracy parameter            =  3.848*E-00009              
               Determinant of tangential matrix       =  4.427*E189782              
               Number of Negative Pivot Element       =        0                    
               Total energy absorbtion                =  8.734*E 00006              
                                                                                    
                                                                                    
                                                                                    
  --------    I N T E R A C T I O N   F U N C T I O N   V A L U E S  Fb(Fy) ---     
                                                                                    
     ELEM  ES     Node1         Midspan         Node2                               
                                                                                    
     1446   0 -0.44(-0.29)  -0.73(-0.65)  -1.00(-1.00)                              
     1447   0 -0.51(-0.47)  -0.55(-0.52)  -0.60(-0.57)                              
     1448   0 -0.42(-0.38)  -0.46(-0.42)  -0.51(-0.47)                              
     1449   0 -0.40(-0.25)  -0.71(-0.63)  -0.98(-0.98)                              
     1451   0 -0.51(-0.48)  -0.55(-0.52)  -0.59(-0.56)                              
     1453                                               Yield at end 1              
     1453                                               Yield at end 2              
     1453   3 -0.07( 0.21)  -0.82(-0.74)  -0.21( 0.04)         O---+---O            
     1454   0 -0.12(-0.05)  -0.24(-0.18)  -0.38(-0.33)                              
     1455                                               Yield at end 2 

-----------Snippet Ends------------

I'm working to isolate two lines namely :-

New load level                         =    1.000  
1453   3 -0.07( 0.21)  -0.82(-0.74)  -0.21( 0.04)         O---+---                  

I did try to change the awk command but I'm getting a null string as output.
Rgds
SShinde

---------- Post updated at 01:42 PM ---------- Previous update was at 12:34 PM ----------

Hi Akshay,
Discovered a shortcoming in the awk command .
The awk command is

awk '/1234/{p=$0;X=NR}/0\-|\-0/ && NR-X == 4{print p RS $0}' file

In the awk command, the absolute value of 4 is creating the problem.
After finding 0- or -0 , I look back till I find 1234, which may occur more than 4 lines behind the first occurrence of 0- or -0.

Can this be rectified !

Rgds
SShinde

Hi,
I don't all understand, but try:

sed -n '/0-/{x;p;x;p;q;};/-0/{x;p;x;p;q;};/1234/x' file

Regards.

Hi disedorgue,
Thanks, it works.
Would it be possible for you to explain this sed command , as I want to learn SED.
Rgds
SShinde

Moving targets make solutions difficult. Plus, is it "O---+---O" or "0---+---0" that you are looking for? Anyhow, try

tac file | awk '/O[+-]+O/ {L=1; print} /New load/ && L {L=0; print} ' | tac
               New load level                         =    1.000                    
     1453   3 -0.07( 0.21)  -0.82(-0.74)  -0.21( 0.04)         O---+---O

In awk (as sed algo):

awk '/0-|-0/{print X"\n"$0;exit};/1234/{X=$0}' file

Regards.

---------- Post updated 29-11-13 at 09:23 AM ---------- Previous update was 28-11-13 at 09:13 PM ----------

-n : only lines explicitly selected for output are written.
here, we treat three pattern: /0-/ , /-0/ and /1234/ .
For the patterns /0-/ and /-0/ , we do code block x;p;x;p;q where:
x : Exchange the contents of the pattern and hold space
p : Write the pattern space to standard output.
q : Quit
For the pattern /1234/ we exchange the contents of the pattern and hold space.
When sed begin a new cycle, the pattern space is empty and the new line will insert in. The hold space is inchanged.
The idea is to catch the pattern /1234/ in hold space and write to output the hold space before the pattern space when the pattern /0-/ or /-0/ are detected and to quit.

Regards.

Thanks disedorgue...very well explained....appreciate the clarity of your expression

If the pattern is always 0-...-0 you can shorten this to

sed -n -e '/0-.*-0/{x;p;x;p;q;}' -e '/1234/h' file

I have chosen two -e "lines" instead of a ";" separator, so it works with all sed versions.

Thanks Made In Germany,
I will give a it a try to interpret it.Please comment on any mistakes on my part.

  1. Look for regex 1234, if true, then pass this to hold buffer.
  2. Look for pattern 0-.-0, if true then exchange, hold buffer goes to pattern space and print pattern space. This prints line containing 1234
    3.Then again exchange and print .This prints line containing 0-.
    -0 .
    4.Then quit. This ensures that ONLY the first instance of the occurrence gets printed.
    Rgds
    SShinde

---------- Post updated at 04:14 AM ---------- Previous update was at 04:07 AM ----------

Just another thought,
Supposing I were looking to print the FIRST THREE instances of the pattern.
How would the sed command look like?
Rgds
SShinde

You got it, well explained!
--
sed is limited - no variables that can be used as counters.
If you have a "do it n-times" requirement then it's time for awk or perl.
BTW sed has a n-times modifier for its s command, and its buffers have multi-line capability, so there might be even an artistic solution...

Artistic solution as here (in red, all pattern find (five) , but print only FIRST FOUR print - see red value in sed command -)
But here, this syntax is not for all sed version:

$ cat co.yy
rwerwerwe rere
fdfefefe fsdfds
rerere ffff trtrt
aaaa 1234 asadsdsd
Xaaa 1234 asadsdsd
Aaaa 1234 asadsdsd
hfjfjfjsjfsf shfshfsjhshs
dssssdsdsdd
dsgdshgsdgdsdgssgdsgdsdhsgdshgshdshdg
akjjkjkj         0---+---0
gfhdfgdfhfgdhhfgdhfgd
sgdhsgdhsdgsdhgsdgsdhhdg
b1234hjhhh ghgsggdgdg
Yaaa 1234 asadsdsd
dddhhdjdhdh
Baaa 1234 asadsdsd
bdagdhdgahadgadg  0---0---+
dagdhdgahadgadg  00+
rwerwerwe rere
fdfefefe fsdfds
rerere ffff trtrt
caaaa 1234 asadsdsd
hfjfjfjsjfsf shfshfsjhshs
dssssdsdsdd
dsgdshgsdgdsdgssgdsgdsdhsgdshgshdshdg
cjjkjkj         0---+---0
gfhdfgdfhfgdhhfgdhfgd
sgdhsgdhsdgsdhgsdgsdhhdg
d1234hjhhh ghgsggdgdg
dddhhdjdhdh
dagdhdgahadgadg  0---0---+
dagdhdgahadgadg  00+
d1234hjhhh ghgsggdgdg
dagdhdgahadgadg  0---0---+
$ sed -n -e '/1234/H' -e '/0-.*-0/H' -e '${x' -e 's/^\n//' -e 's/$/\n/' -e ':loop' -e 's/\([^\n]*1234[^\n]*\n\)\([^\n]*1234[^\n]*\n\)/\2/' -e 't loop' -e 's/\(\([^\n]*1234[^\n]*\n[^\n]*\(0-\)*\(-0\)*[^\n]*\n\)\{4\}\).*/\1/;s/\n$//p' -e '}' co.yy
Aaaa 1234 asadsdsd
akjjkjkj         0---+---0
Baaa 1234 asadsdsd
bdagdhdgahadgadg  0---0---+
caaaa 1234 asadsdsd
cjjkjkj         0---+---0
d1234hjhhh ghgsggdgdg
dagdhdgahadgadg  0---0---+

:eek:Phew!:b:

@OP: Does it have to be sed as there is a much shorter solution using awk...

awk '/1234/{s=$0} /0-.*-0/{if(++n>3) exit; else print s RS $0}' file