1. ホーム
  2. パイソン

[解決済み】'print'出力をファイルにリダイレクトするには?

2022-04-18 19:10:50

質問

Pythonを使って、printを.txtファイルにリダイレクトしたいのですが。私は for のループがあり、それが print をリダイレクトしながら、それぞれの.bamファイルに対して出力します。 すべて を1つのファイルに出力します。ということで、入れてみました。

f = open('output.txt','w')
sys.stdout = f

をスクリプトの冒頭に追加しました。しかし、.txt ファイルには何も表示されません。 私のスクリプトは

#!/usr/bin/python

import os,sys
import subprocess
import glob
from os import path

f = open('output.txt','w')
sys.stdout = f

path= '/home/xxx/nearline/bamfiles'
bamfiles = glob.glob(path + '/*.bam')

for bamfile in bamfiles:
    filename = bamfile.split('/')[-1]
    print 'Filename:', filename
    samtoolsin = subprocess.Popen(["/share/bin/samtools/samtools","view",bamfile],
                                  stdout=subprocess.PIPE,bufsize=1)
    linelist= samtoolsin.stdout.readlines()
    print 'Readlines finished!'

で、何が問題なんだ?これ以外の方法 sys.stdout ?

このような結果が必要です。

Filename: ERR001268.bam
Readlines finished!
Mean: 233
SD: 10
Interval is: (213, 252)

解決方法は?

一番わかりやすいのは、ファイルオブジェクトに印刷することでしょう。

with open('out.txt', 'w') as f:
    print('Filename:', filename, file=f)  # Python 3.x
    print >> f, 'Filename:', filename     # Python 2.x

しかし、stdoutをリダイレクトすることも私には有効です。 このような単発のスクリプトでは、おそらく問題ないでしょう。

import sys

orig_stdout = sys.stdout
f = open('out.txt', 'w')
sys.stdout = f

for i in range(2):
    print('i = ', i)

sys.stdout = orig_stdout
f.close()

Python 3.4 以降では、これを行うためのシンプルなコンテキストマネージャが用意されています。 標準ライブラリの :

from contextlib import redirect_stdout

with open('out.txt', 'w') as f:
    with redirect_stdout(f):
        print('data')

シェル自身から外部へリダイレクトすることも選択肢の一つであり、望ましい場合が多い。

./script.py > out.txt

その他の質問

スクリプトの最初のファイル名は何ですか? 初期化されていないようですが。

最初に推測したのは、globがbamfilesを見つけられず、そのためforループが実行されないということです。 フォルダが存在することを確認し、スクリプトでbamfilesを出力してください。

また os.path.join と os.path.basename があります。 を使用して、パスとファイル名を操作します。