简体   繁体   中英

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.

You may use this sed that ignore lines that already have a closing ) :

cat file
print("""Some multi line text etc...
print("Some single line text"
print("Some single ""line text"
print("Some single line text")

sed '/print("""/!s/print(".*[^)]$/&)/' file
print("""Some multi line text etc...
print("Some single line text")
print("Some single ""line text")
print("Some single line text")

Pattern print(".*[^)]$ matches a line with test from print(" with a non- ) character in the end. &) places ) at the end of matching pattern.

Is this all you're trying to do?

$ cat file
print("""Some multi line text etc...
print("Some single line text"

$ sed 's/print("[^"].*/&)/' file
print("""Some multi line text etc...
print("Some single line text")

If not then please edit your question to show more truly representative sample input/output that includes cases this doesn't work for.

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 ) .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM