Re: Delete only the nth block of text, multi-line

"[email protected] [sed-users]" <[email protected]>
Newsgroups gmane.editors.sed.user
Message-ID <[email protected]>
Hello Daniel, 

 Is the /e (evaluate) option to the s/// command a new addition to sed?
 And when the expr command is evaluated the very first time, the value of & 
 is null. Is that promoted to a numeric zero when run thru expr?
 

 Actually there's no need to increment the counter by appending the hold space with dots, for in this particular scenario the increment needs to happen only at the beginning of each block. So we can make use of the "H" command.
 This saves the us from eXchanging the hold<=>pattern spaces.
 

 sed -ne '
 ## Objective:- To delete the 3rd-block from input.
 ## Where a block begins with [ on a line by itself
 ## and the block ends with a ] on a separate line.
 

 # print the non-block lines right away.
 /^\[$/,/^\]$/!bprint
 

 # increment the block counter
 H
 

 # accumulate the block
 :loop
    $bprint;N
 /\n\]$/!bloop
 

 # we now have one whole block in the pattern space.
 # check whether this is the 3rd block?
 x
 s/^\(\n\[\)\{3\}$//;tremaining
 # no => this aint the block
 x;bprint
 # yes => this block to be deleted
 :remaining
    n;p
 bremaining
 

 :print
 p
 ' yourfile

 

 P.S.:-

   i ) Not all seds support the \(...\)\{number\} syntax. But GNU sed for sure does. In case it doesn't, then we could do one of the two things:
          a ) At the point when we interrogate the hold space for the block to be deleted, we take the steps:
                       x;s/\n//g; s/^\[\{3\}$//;tremaining;s/./\n&/g;x;bprint
         b ) Else use the previous method of incrementing the hold space by appending dots to it.
 -Rakesh

---In [email protected], <dgoldman@...> wrote :

 That's very clever, the way you "increment the block counter" by adding dots to the hold pattern. Below is a variation on your solution, storing a number with expr, instead of a using series of dots. It's no better, just a little different, and helps me understand your solution. 
 
 
 Daniel 
 
 
 -------------------------------------------- 
 
 
 $ cat in 
 foo 
 [ 
 aaa 1 
 bbb 1 
 ccc 1 
 ] 
 [ 
 ccc 2 
 bbb 2 
 aaa 2 
 ] 
 [ 
 bbb 3 
 ccc 3 
 aaa 3 
 ] 
 [ 
 bbb 4 
 aaa 4 
 ccc 4 
 ] 
 bar 
 
 
 --------------------------------------- 
 
 
 $ cat sed3.txt 
 ## Objective: To delete the 3rd-block from input. 
 ## Where a block begins with [ on a line by itself 
 ## and the block ends with a ] on a separate line. 
 
 
 # skip the non-block lines right away. 
 /^\[$/,/^\]$/!b end 
 
 
 # increment the block counter 
 x; s/.*/expr & + 1/e; x 
 
 
 # accumulate the block 
 :loop $b end; N; /\n\]$/ ! b loop 
 
 
 # we now have the whole block in the pattern space. 
 # check whether this is the 3rd block? 
 x 
 # yes: print remainder after the block 
 /^3$/ { :remaining n; p; b remaining } 
 # no: just display block as is 
 x 
 
 
 :end p 
 
 ----------------------------------------------------- 
 
 
 $ sed -n -f sed3.txt in 
 foo 
 [ 
 aaa 1 
 bbb 1 
 ccc 1 
 ] 
 [ 
 ccc 2 
 bbb 2 
 aaa 2 
 ] 
 [ 
 bbb 4 
 aaa 4 
 ccc 4 
 ] 
 bar 
 
 
 
 
 
 [Non-text portions of this message have been removed]




[Non-text portions of this message have been removed]
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.