簡體   English   中英

從Python調用帶有可變輸入和文件輸出作為參數的Perl腳本

[英]Invoking perl script with variable input and file output as arguments from python

我有一個可以從控制台執行的perl腳本,如下所示:

perl perlscript.pl -i input.txt -o output.txt --append

我想從我的python代碼執行此腳本。 我發現subprocess.Popen可以用於連接到perl,並且可以通過它傳遞參數。 但是,我也想傳遞一個變量(通過分割文本文件制成)來代替input.txt。 我已經嘗試了以下方法,但是它似乎不起作用,並在第8行給出了明顯的TypeError:

import re, shlex, subprocess, StringIO
f=open('fulltext.txt','rb')
text= f.read()
l = re.split('\n\n',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)

是否有任何其他變通方法嗎?

編輯:這是文件fulltext.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腳本。 所有文件都在同一目錄中。

您可能對os模塊字符串格式感興趣

編輯

我想我明白你現在想要什么。 如果我錯了,請糾正我,但我認為:

  • 您想將fulltext.txt拆分為塊。
  • 每個塊包含一個seq(number)
  • 您想為每個塊運行一次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('\n\n')

# 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() )。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM