sed 将两个搜索条件应用于一行,然后替换

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

我想做以下替换

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

条件是一行包含print(但不能包含print(""".

它应该匹配的行是

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

像这样的行应该匹配

print("Some single line text"

现在很容易匹配一个或排除另一个,但我无法将这两个条件组合到一个命令中。例如

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

匹配所有行 print( 但也匹配我想省略的行 print("""。另一方面,我可以使用 print("""

跳过所有行
sed -ne /print("""/! s/$/)/p python2.py

但这包括所有其他行,甚至包括没有 print( 的行。有什么方法可以将这两个条件结合起来,以便仅当一行的两个条件都为真时才应用替换?

备注:

我知道我可以执行两次 sed 运行s,首先对所有 print( 行进行替换,然后执行第二次 sed 运行,删除新的行仅在 print(""" 行中替换 )。我想知道是否可以一次性完成,所以这不是我要找的答案。

有了 GNU sed,你可以使用

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

参见online demo

详情:

  • /print("""/! - 如果找到 print(""",则跳过行
  • {/print("/s/$/)/} - 否则,如果行包含 print(",则将行尾替换为 )

您可以使用此 sed 来忽略已经结束的行 ):

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(".*[^)]$ 匹配来自 print(" 且末尾为非 ) 字符的带有测试的行。 &)) 放在匹配模式的末尾。

这就是你想要做的全部吗?

$ 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")

如果不是,请编辑您的问题以显示更具代表性的示例 input/output,其中包括不适用于此的案例。