Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.0k views
in Technique[技术] by (71.8m points)

bash - Delete n1 previous lines and n2 lines following with respect to a line containing a pattern

sed -e '/XXXX/,+4d' fv.out

I have to find a particular pattern in a file and delete 5 lines above and 4 lines below it simultaneously. I found out that the line above removes the line containing the pattern and four lines below it.

sed -e '/XXXX/,~5d' fv.out

In sed manual it was given that ~ represents the lines which is followed by the pattern. But when i tried it, it was the lines following the pattern that was deleted.

So, how do I delete 5 lines above and 4 lines below a line containing the pattern simultaneously?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

One way using sed, assuming that the patterns are not close enough each other:

Content of script.sed:

## If line doesn't match the pattern...
/pattern/ ! { 

    ## Append line to 'hold space'.
    H   

    ## Copy content of 'hold space' to 'pattern space' to work with it.
    g   

    ## If there are more than 5 lines saved, print and remove the first
    ## one. It's like a FIFO.
    /(
[^
]*){6}/ {

        ## Delete the first '
' automatically added by previous 'H' command.
        s/^
//
        ## Print until first '
'.
        P   
        ## Delete data printed just before.
        s/[^
]*//
        ## Save updated content to 'hold space'.
        h   
    } 

### Added to fix an error pointed out by potong in comments.
### =======================================================
    ## If last line, print lines left in 'hold space'.
    $ { 
        x   
        s/^
//
        p   
    } 
### =======================================================


    ## Read next line.
    b   
}

## If line matches the pattern...
/pattern/ {

    ## Remove all content of 'hold space'. It has the five previous
    ## lines, which won't be printed.
    x   
    s/^.*$//
    x   

    ## Read next four lines and append them to 'pattern space'.
    N ; N ; N ; N 

    ## Delete all.
    s/^.*$//
}

Run like:

sed -nf script.sed infile

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...