簡體   English   中英

如何通過Pythons子進程管道傳輸到文件或Shell程序?

[英]How do I pipe to a file or shell program via Pythons subprocess?

我正在處理一些相當大的壓縮文本文件,這些文件必須解壓縮,編輯和重新壓縮。 我使用Python的gzip模塊進行解壓縮和壓縮,但是我發現我當前的實現遠非最佳:

input_file = gzip.open(input_file_name, 'rb')

output_file = gzip.open(output_file_name, 'wb')

for line in input_file:
    # Edit line and write to output_file

這種方法的速度差得令人難以忍受-可能是因為使用gzip模塊進行每行迭代會涉及大量開銷:我最初還運行了一個行數例程,其中我-使用gzip模塊-讀取文件的塊,然后計算每個塊中的換行符數量非常快!

因此,優化措施之一絕對應該是讀取我的文件,然后在解壓縮這些塊之后才進行每行迭代。

作為一項額外的優化,我看到了一些建議,可以通過子進程將Shell命令解壓縮。 使用這種方法,上面第一行的內容可能是:

from subprocess import Popen, PIPE

file_input = Popen(["zcat", fastq_filename], stdout=PIPE)

input_file = file_input.stdout

使用這種方法,input_file成為一個類似文件的對象。 我不知道就可用屬性和方法而言,它與真實文件對象有何不同,但一個區別是,顯然它不能使用搜索,因為它是流而不是文件。

這確實運行得更快,並且應該-除非您在單台核心計算機上運行腳本,否則聲明是這樣。 后者必須表示,如果可能的話,子進程會自動將不同的線程運送到不同的內核,但是我不是專家。

現在是我當前的問題:我想以類似的方式壓縮輸出。 也就是說,我不想使用Python的gzip模塊,而是將其通過管道傳遞給子進程,然后調用shell gzip。 這樣,我可能可以在單獨的內核中進行讀取,編輯和編寫,這對我來說聽起來非常有效。 我對此進行了一些細微的嘗試,但是嘗試寫入output_file導致文件為空。 最初,我使用touch命令創建一個空文件,因為如果文件不存在,則Popen失敗:

call('touch ' + output_file_name, shell=True)

output = Popen(["gzip", output_file_name], stdin=PIPE)

output_file = output.stdin

非常感謝您的幫助,我正在使用Python 2.7。 謝謝。

您的意思是output_file = gzip_process.stdin 之后,您可以像以前使用gzip.open()對象一樣使用output_file (不查找)。

如果結果文件為空,請檢查是否在Python腳本末尾調用了output_file.close()gzip_process.wait() 同樣, gzip的用法可能不正確:如果gzip將壓縮的輸出寫入其stdout,則傳遞stdout=gzip_output_file ,其中gzip_output_file = open(output_file_name, 'wb', 0)

這是一個如何完成此工作的示例:

#!/usr/bin/env python

from subprocess import Popen, PIPE

output = ['this', 'is', 'a', 'test']

output_file_name = 'pipe_out_test.txt.gz'

gzip_output_file = open(output_file_name, 'wb', 0)

output_stream = Popen(["gzip"], stdin=PIPE, stdout=gzip_output_file)  # If gzip is supported

for line in output:
    output_stream.stdin.write(line + '\n')

output_stream.stdin.close()
output_stream.wait()

gzip_output_file.close()

如果我們的腳本只寫到控制台,而我們想壓縮輸出,則與上述命令等效的shell命令可能是:

script_that_writes_to_console | gzip > output.txt.gz

暫無
暫無

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

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