我的子进程调用应该调用tabix 1kg.phase1.snp.bed.gz -B test.bed | awk '{FS="\t";OFS="\t"} $4 >= 10'
,但由于其中包含"
和'
,因此给出了错误。我尝试使用r
作为原始字符串,但我无法找出正确的组合来防止错误。我目前的电话看起来像:
snp_tabix = subprocess.Popen(["tabix", tgp_snp, "-B", infile, "|", "awk", """'{FS="\t";OFS="\t"}""", "$4", ">=", maf_cut_off, r"'"], stdout=subprocess.PIPE)
出现错误TypeError: execv() arg 2 must contain only strings
答案 0 :(得分:3)
r"'"
不是问题。您很可能将maf_cut_off
作为整数传递,这是不正确的。您应该使用str(maf_cut_off)
。
答案 1 :(得分:1)
有几个问题。您正在尝试执行shell命令(命令中有一个管道|
)。因此即使将所有变量转换为字符串也无法工作。
您可以使用shell执行它:
from pipes import quote
from subprocess import check_output
cmd = r"""tabix %s -B %s | awk '{FS="\t";OFS="\t"} $4 >= %d'""" % (
quote(tgp_snp), quote(infile), maf_cut_off)
output = check_output(cmd, shell=True)
或者您可以使用pipe recipe from subprocess
' docs:
from subprocess import Popen, PIPE
tabix = Popen(["tabix", tgp_snp, "-B", infile], stdout=PIPE)
awk = Popen(["awk", r'{FS="\t";OFS="\t"} $4 >= %d' % maf_cut_off],
stdin=tabix.stdout, stdout=PIPE)
tabix.stdout.close() # allow tabix to receive a SIGPIPE if awk exits
output = awk.communicate()[0]
tabix.wait()
或者您可以使用plumbum
that provides some syntax sugar for shell commands:
from plumbum.cmd import tabix, awk
cmd = tabix[tgp_snp, '-B', infile]
cmd |= awk[r'{FS="\t";OFS="\t"} $4 >= %d' % maf_cut_off]
output = cmd() # run it and get output
另一种选择是在纯Python中重现awk
命令。要使第4个字段的所有行以数字方式大于或等于maf_cut_off
(作为整数):
from subprocess import Popen, PIPE
tabix = Popen(["tabix", tgp_snp, "-B", infile], stdout=PIPE)
lines = []
for line in tabix.stdout:
columns = line.split(b'\t', 4)
if len(columns) > 3 and int(columns[3]) >= maf_cut_off:
lines.append(line)
output = b''.join(lines)
tabix.communicate() # close streams, wait for the subprocess to exit
tgp_snp
,infile
应为字符串,maf_cut_off
应为整数。
您可以使用bufsize=-1
(Popen()
的参数)来提高时间效果。