需要使用子流程模块在python脚本中运行AWK命令

2024-04-27 15:46:24 发布

您现在位置:Python中文网/ 问答频道 /正文

c1 = "'BEGIN{FS = OFS = \",\"}{if(toupper($11) ~ \"DVT\"){$(NF+1) = NR==1 ? \"indication\" : \"DVT\"}else if(toupper($11) ~ \"AFIB\"){$(NF+1) = NR==1 ? \"indication\" : \"AFIB\"}else{$(NF+1) = NR==1 ? \"indication\" : \"TESTING\"}} 1'"

print(c1)

p1=subprocess.Popen(["awk",c1,"abc.csv"],stdout=outfile)

p1.communicate()

此命令在shell脚本中运行良好。因此,命令参数似乎很好。但是,在运行python时,我不断得到错误:“表达式中的字符“”无效。”


Tags: 命令iftestingfselsenrbeginc1
1条回答
网友
1楼 · 发布于 2024-04-27 15:46:24

外部引号是不必要的。当您有一个shell时,单引号是保护Awk脚本免受shell攻击所必需的;但是在这里,你没有壳。然后你可以也应该摆脱所有这些反斜杠

如果您只需要运行子进程,那么您应该更喜欢subprocess.run()而不是裸Popen,然后在完成后继续您的程序

c1 = '''BEGIN{FS = OFS = ","}
{if(toupper($11) ~ "DVT"){$(NF+1) = NR==1 ? "indication" : "DVT"}
 else if(toupper($11) ~ "AFIB"){$(NF+1) = NR==1 ? "indication" : "AFIB"}
 else{$(NF+1) = NR==1 ? "indication" : "TESTING"}} 
1'''

print(c1)

result = subprocess.run(["awk", c1, "abc.csv"],
    stdout=outfile)

然而,将Awk作为Python的子进程运行几乎总是不必要的。您应该能够将其重构为大致相同数量的Python代码

with open("abc.csv") as infile:
    firstline = True
    for line in infile:
        fields = line.rstrip("\n").split(",")
        if firstline:
            added = "indication"
        else:
            ind = fields[10].upper()
            if "DVT" in ind:
                added = "DVT"
            elif "AFIB" in ind:
                added = "AFIB"
            else:
                added = "TESTING"
        fields.append(added)
        outfile.write(",".join(fields) + "\n")
        firstline = False

这有点冗长,但这主要是因为我使用了更具描述性的变量名。如果您的输入文件实际上是一个CSV文件,那么Python标准库中的csv模块可以方便地替换拆分逻辑等,尽管它随后引入了自己的一些其他特性。如果您必须在CSV中处理带引号的逗号等,这就是它真正增加价值的地方

所有这些都很重要,Awk更简洁,但那是因为它更专业。将其嵌入Python代码的主要缺点是,读者必须理解这两种语言才能理解代码(尽管避免外部进程也很好)。我敢猜测,您收到了这个Awk代码,但没有解释它是如何工作的,或者如果它坏了,如何修复它

相关问题 更多 >