>我有一个可以从控制台执行的perl脚本,如下所示:
perl perlscript.pl -i input.txt -o output.txt --append
我想从我的 python 代码中执行此脚本。我发现subprocess.Popen
可以用来连接到perl,我可以用它传递我的论点。但是,我还想传递一个变量(通过拆分文本文件来代替输入.txt。我已经尝试了以下内容,但它似乎不起作用,并且在第 8 行给出了明显的 TypeError:
import re, shlex, subprocess, StringIO
f=open('fulltext.txt','rb')
text= f.read()
l = re.split('nn',str(text))
intxt = StringIO.StringIO()
for i in range(len(l)):
intxt.write(l[i])
command_line='perl cnv_ltrfinder2gff.pl -i '+intxt+' -o output.gff --append'
args=shlex.split(command_line)
p = subprocess.Popen(args)
还有其他解决方法吗?
编辑:这是文件全文.txt的示例。条目由一行分隔。
Predict protein Domains 0.021 second
>Sequence: seq1 Len:13143 [1] seq1 Len:13143 Location : 9 - 13124 Len: 13116 Strand:+ Score : 6 [LTR region similarity:0.959] Status : 11110110000 5'-LTR : 9 - 501 Len: 493 3'-LTR : 12633 - 13124 Len: 492 5'-TG : TG , TG 3'-CA : CA , CA TSR : NOT FOUND Sharpness: 1,1 Strand + : PBS : [14/20] 524 - 543 (LysTTT) PPT : [12/15] 12553 - 12567
Predict protein Domains 0.019 second
>Sequence: seq5 Len:11539 [1] seq5 Len:11539 Location : 7 - 11535 Len: 11529 Strand:+ Score : 6 [LTR region similarity:0.984] Status : 11110110000 5'-LTR : 7 - 506 Len: 500 3'-LTR : 11036 - 11535 Len: 500 5'-TG : TG , TG 3'-CA : CA , CA TSR : NOT FOUND Sharpness: 1,1 Strand + : PBS : [15/22] 515 - 536 (LysTTT) PPT : [11/15] 11020 - 11034
我想将它们分开并将每个入口块传递给perl脚本。所有文件都位于同一目录中。
您可能对操作系统模块感兴趣和字符串格式
编辑
我想我现在想要什么。 如果我错了,请纠正我,但我认为:
- 你想把你的全文.txt分成块。
- 每个块都包含一个 seq(数字)
- 你想为每个块运行一次perl脚本,作为输入文件你的seq(number)
如果这是您想要的,则可以使用以下代码。
import os
in_file = 'fulltext.txt'
seq = []
with open(in_file,'r') as handle:
lines = handle.readlines()
for i in range(0,len(lines)):
if lines[i].startswith(">"):
seq.append(lines[i].rstrip().split(" ")[1])
for x in seq:
command = "perl perl cnv_ltrfinder2gff.pl -i %s.txt -o output.txt --append"%x
os.system(command)
--infile
选项的文档:
输入文件的路径。如果未提供输入文件,则程序 将期待来自 STDIN 的输入。
您可以省略--infile
并通过管道 (stdin) 传递输入:
#!/usr/bin/env python
from subprocess import Popen, PIPE
with open('fulltext.txt') as file: # read input data
blocks = file.read().split('nn')
# run a separate perl process for each block
args = 'perl cnv_ltrfinder2gff.pl -o output.gff --append'.split()
for block in blocks:
p = Popen(args, stdin=PIPE, universal_newlines=True)
p.communicate(block)
if p.returncode != 0:
print('non-zero exit status: %s on block: %r' % (p.returncode, block))
您可以同时运行多个perl
脚本:
from multiprocessing.dummy import Pool # use threads
def run((i, block)):
filename = 'out%03d.gff' % i
args = ['perl', 'cnv_ltrfinder2gff.pl', '-o', filename]
p = Popen(args, stdin=PIPE, universal_newlines=True, close_fds=True)
p.communicate(block)
return p.returncode, filename
exit_statuses, filenames = zip(*Pool().map(run, enumerate(blocks, start=1)))
它并行运行多个(等于系统上的 CPU 数量)子进程。您可以指定不同数量的工作线程(传递给 Pool()
)。