2017-04-14 1 views
0

私はgtfファイルを読んでから、それを編集して(サブプロセス、grep、awkを使って)、パンダに読み込みます。コンソール上のファイルを直接処理する方法(StringIOを使用する場合と使用しない場合)

私はヘッダー情報(#で示される)を持つファイル名を持っていますので、まずgrepして削除する必要があります。私はPythonでそれを行うことができますが、より効率的な処理を行うためにパイプラインにgrepを導入したいと思います。

import subprocess 
from io import StringIO 

gtf_file = open('chr2_only.gtf', 'r').read() 
gtf_update = subprocess.Popen(["grep '^#' " + StringIO(gtf_file)], shell=True) 

gtf_update = subprocess.Popen(["grep '^#' " + gtf_file], shell=True) 

をこれらのコードの両方が、それがあった第一の試みのために、エラーをスロー:

Traceback (most recent call last): 
    File "/home/everestial007/PycharmProjects/stitcher/pHASE-Stitcher-Markov/markov_final_test/phase_to_vcf.py", line 39, in <module> gtf_update = subprocess.Popen(["grep '^#' " + StringIO(gtf_file)], shell=True) 
TypeError: Can't convert '_io.StringIO' object to str implicitly 

しかし、私はやってみました

、もし私がfilenを指定したらAME直接それが動作:

gtf_update = subprocess.Popen(["grep '^#' chr2_only.gtf"], shell=True) 

を、出力は次のとおりです。

<subprocess.Popen object at 0x7fc12e5ea588> 
#!genome-build v.1.0 
#!genome-version JGI8X 
#!genome-date 2008-12 
#!genome-build-accession GCA_000004255.1 
#!genebuild-last-updated 2008-12 

誰かがこのような問題のための様々な例を提供してください、ともなぜ私はエラーを取得しています、なぜ/どのように説明してもらえコンソール/メモリにロードされたファイルに対してサブプロセスを直接実行することは可能でしょうか?

は、私はまた、call, check_call, check_output, etc.subprocessを使用してみましたが、私はこれらのように、いくつかの異なるエラーメッセージを得ている:ここで

OSError: [Errno 7] Argument list too long 

Subprocess in Python: File Name too long 
+0

私は以前に "Pythonでサブプロセス:ファイル名が長すぎる"と見ました。私が誤ってファイル名の文字列の代わりに、開いているファイルの中のテキストをPopenの引数として渡していたとき、これは私に起こりました。 'gtf_update = subprocess.Popen([" grep '^#' chr2_only。'gtf_update.communicate()'を使用してそのコマンドを出力することができます。 – JacobIRR

+0

'grep'コマンドでは、あなたの作業例のように* filename *を渡す必要があります。文字列 '' grep '^#' "'にStringIOオブジェクトまたはファイルオブジェクトを追加しようとすると、Pythonはそれらを文字列に変換できません。代わりにファイル名を追加してください。 –

+0

しかし、なぜなら、このファイルをパイプラインの別々の枝に使う必要があるからです。だから、私はPythonの方法で 'data = open(.... ).read() 'を実行した後、この 'data'を使って別のものを実行してください。同じファイルを何度も何度も読まないでメモリと時間を節約しようとしています – everestial007

答えて

2

は、あなたがすることができます可能な解決策でありますgrepに文字列を送ります。基本的には、Popenコンストラクタで、stdinとstdoutを介して呼び出されたプログラムと通信することを宣言します。その後、通信を介して入力を送信し、通信からの戻り値として出力を受け取ります。

#!/usr/bin/python 

import subprocess 

gtf_file = open('chr2_only.gtf', 'r').read() 
gtf_update = subprocess.Popen(["grep '^#' "], shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE) 

# stdout, stderr (but latter is empty) 
gtf_filtered, _ = gtf_update.communicate(gtf_file) 

print gtf_filtered 

shell=Trueを使用しないことをおすすめします。したがって、popenのラインが

gtf_update = subprocess.Popen(["grep", '^#'], shell=False, stdin=subprocess.PIPE, stdout=subprocess.PIPE) 

根拠として記述する必要がありますあなたは、単一の実行可能ファイルに引数を解析するためにシェルを必要としないことです。したがって、不要なオーバーヘッドを回避できます。少なくともセキュリティ上の観点からは、ユーザーからの入力に応じて(ファイル名が|のように)、引数が安全でない可能性がある場合は、セキュリティの観点からも優れています。

パフォーマンスの観点からは、grepでファイルを直接読み取るのは、最初にpythonでファイルを読み取り、grepに送信するよりも速いことに注意してください。

関連する問題