如何在python脚本中调用sed命令?

时间:2018-11-27 14:32:57

标签: python linux unix

通过python脚本,我试图像脚本中一样通过subprocess.call() sed命令。

file = "a.xml"
updateData= "(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=abc)(PORT=1234)))(CONNECT_DATA=(SERVICE_NAME=centraldb)))"
subprocess.call(["sed", "-i", 's#<DB_CONNECT_STRING>.*</DB_CONNECT_STRING>#<DB_CONNECT_STRING>updateData</DB_CONNECT_STRING>#', file])

当我在shell脚本或命令中运行命令时,它运行正常,但是在python中,我得到的结果是“无输入文件”。知道如何解决该错误吗?

a.xml看起来像这样。

<?xml version = '1.0' encoding = 'UTF-8'?> 
<!DOCTYPE properties SYSTEM "java.sun.com/dtd/properties.dtd"> 

<properties> <!-- Database server details --> 
    <DB_CONNECT_STRING>(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=abc)(PORT=1521)))(CONNECT_DATA=(SERVICE_NAME=cdb)))</DB_CONNECT_STRING> 
</properties>

1 个答案:

答案 0 :(得分:0)

您确实不需要或不想使用外部子进程。

import fileinput

updateData = "(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=abc)(PORT=1234)))(CONNECT_DATA=(SERVICE_NAME=centraldb)))"

for line in fileinput.input('a.xml', inplace=True):
    try:
        prefix, tail = line.split('<DB_CONNECT_STRING>', 1)
        _, suffix = tail.split('</DB_CONNECT_STRING>', 1)
        line = prefix + '<DB_CONNECT_STRING>' + updateData + '</DB_CONNECT_STRING>' + suffix
    except ValueError:
        # <DB_CONNECT_STRING> or close tag not found -- don't replace
        pass
    print(line)

为记录起见,引号内的updateData不会神奇地变为变量updateData的值,因此这是您尝试的另一个问题。

即席XML处理仍然是一个主要问题。适当的解决方案将使用XML解析器,也许使用XSLT来更新文件。 (另一方面,如果您知道该行永远不会在开始和结束标记之外包含任何内容,则可以对上述脚本进行一些简化。第三,在XML标记内的即席s表达式如果您对此有任何控制的话,您似乎真的想更彻底地重新考虑配置文件格式。)