需要在 python 脚本中使用子进程模块 运行 AWK 命令
Need to run AWK command in python script using subprocess module
c1 = "'BEGIN{FS = OFS = \",\"}{if(toupper() ~ \"DVT\"){$(NF+1) = NR==1 ? \"indication\" : \"DVT\"}else if(toupper() ~ \"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 期间,我不断收到错误消息:“表达式中的字符无效。”
外引号是不必要的。当您有 shell 时,单引号是保护 Awk 脚本免受 shell 影响所必需的;但是在这里,您没有 shell。然后你可以也应该去掉所有那些反斜杠。
如果你只需要 运行 的子进程,你应该更喜欢 subprocess.run()
而不是裸 Popen
,然后在完成后继续你的程序。
c1 = '''BEGIN{FS = OFS = ","}
{if(toupper() ~ "DVT"){$(NF+1) = NR==1 ? "indication" : "DVT"}
else if(toupper() ~ "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 代码的主要缺点是 reader 必须理解两种语言才能理解代码(尽管避免外部进程也总是很好)。我敢猜测,您收到此 Awk 代码时没有任何解释它是如何工作的,或者如果它损坏了如何修复...?
c1 = "'BEGIN{FS = OFS = \",\"}{if(toupper() ~ \"DVT\"){$(NF+1) = NR==1 ? \"indication\" : \"DVT\"}else if(toupper() ~ \"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 期间,我不断收到错误消息:“表达式中的字符无效。”
外引号是不必要的。当您有 shell 时,单引号是保护 Awk 脚本免受 shell 影响所必需的;但是在这里,您没有 shell。然后你可以也应该去掉所有那些反斜杠。
如果你只需要 运行 的子进程,你应该更喜欢 subprocess.run()
而不是裸 Popen
,然后在完成后继续你的程序。
c1 = '''BEGIN{FS = OFS = ","}
{if(toupper() ~ "DVT"){$(NF+1) = NR==1 ? "indication" : "DVT"}
else if(toupper() ~ "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 代码的主要缺点是 reader 必须理解两种语言才能理解代码(尽管避免外部进程也总是很好)。我敢猜测,您收到此 Awk 代码时没有任何解释它是如何工作的,或者如果它损坏了如何修复...?