Search code examples
regexsedlogical-operatorslogical-and

sed apply two search conditions to a single line and then substitute


Id like to do do the following substitution

sed 's/$/)/' python2.py

with the condition that a line contains print( but it may not contain print(""".

A line that it should not match would be

print("""Some multi line text etc... 

While lines like this should be matched

print("Some single line text"

Now its easy to match one or to exclude the other but i fail to combine both conditions into one command. For example

sed -ne '/print(/s/$/)/p' python2.py

Does match all lines with print( but also the ones which i would like to omit with print(""". On the other hand i can skip all lines with print(""" with

sed -ne /print("""/! s/$/)/p python2.py

But that includes all other lines even those without print(. Is there any way to combine both conditions such that the substition is only applied when both conditions are true for a line ?

As a note :

I am aware that i can do two sed runs where i first do the substitutions for all print( lines and then do a second sed run where i remove the newly substituted ) only in the print(""" lines. I'd like to know if it is possible to do it in one go so that is not an answer that i am looking for.


Solution

  • With GNU sed, you can use

    sed '/print("""/!{/print("/s/$/)/}' file > newfile
    

    See the online demo.

    Details:

    • /print("""/! - if print(""" is found, skip the line
    • {/print("/s/$/)/} - else, if line contains print(", replace the end of line with ).