Search code examples
sed

Multiple sed commands into one


I have 3 sed commands. How to combine the below sed commands?

sed -e '15,19d' 
sed -n '/something/,+16p' 
sed -e '1712,1747d' 

I want to combine them say something like this

sed -e 'command1' -e 'command2' -e 'command3'

But it is not working because -n can't be combine.


Solution

  • As a single command,

    sed -ne '/something/,+16p'
    

    is the same as

    sed -e '/something/,+16!d'
    

    i.e. don't delete 16 lines after something.

    But combining them into one command

    sed -e '15,19d' -e '/something/,+16!d' -e '1712,1747d
    

    might give different results when "something" appears before line 15.

    Why? You need to understand how sed works. It reads the input line by line and for each line, it decides which rules are applicable. If something appears before line 15, it starts printing from there, because the second rule matches; but stops printing from line 15 because of the first rule. In the original pipeline, though, the lines are removed first, so +16 extends over some more lines that weren't printed.

    I don't see a way how to fix this problem in sed.

    Demo:

    #!/bin/bash
    input() {
        printf 'A %d\n' {1..10}
        echo something
        printf 'B %d\n' {1..20}
    }
    
    diff -y <(
        input | sed -e '15,19d' | sed -ne '/something/,+16p'
    ) <(
        input | sed -e '15,19d;/something/,+16!d'
    )