2013-07-19 23 views
6

ディレクトリ内のすべてのファイルを1つのファイルに連結するためのスクリプトを作成しました。ディレクトリ内のすべてのファイルを1つのファイルに連結するpythonスクリプト

これは

  1. 慣用のpythonの面でここ

  • 時間がスニペットで、最適化することができます:

    import time, glob 
    
    outfilename = 'all_' + str((int(time.time()))) + ".txt" 
    
    filenames = glob.glob('*.txt') 
    
    with open(outfilename, 'wb') as outfile: 
        for fname in filenames: 
         with open(fname, 'r') as readfile: 
          infile = readfile.read() 
          for line in infile: 
           outfile.write(line) 
          outfile.write("\n\n") 
    
  • +7

    時間に最適ですか? "cat * .txt> all.txt"を使用してください:) –

    +0

    [複数のテキストファイルを1つのテキストファイルにまとめてPythonを使って合成する]の可能な複製(http://stackoverflow.com/questions/17749058/combine-multiple-text-files- 1つのテキストファイルを使用するPython) – llb

    答えて

    23

    使用shutil.copyfileobj:メモリに全部を読まずに直接ファイルオブジェクトのINES、

    import shutil 
    
    with open(outfilename, 'wb') as outfile: 
        for filename in glob.glob('*.txt'): 
         if filename == outfilename: 
          # don't want to copy the output into the output 
          continue 
         with open(filename, 'rb') as readfile: 
          shutil.copyfileobj(readfile, outfile) 
    

    shutiloutfileのFileObjectに書き込む、チャンクでreadfileオブジェクトから読み込みます直接。行末を見つけるためのオーバーヘッドを必要としないので、readline()または反復バッファを使用しないでください。

    読み取りと書き込みの両方に同じモードを使用します。これはPython 3を使用する場合に特に重要です。ここではバイナリモードを使用しました。

    +0

    同じモードを書き込みと読み取りに使用するのはなぜ重要ですか? –

    +1

    @JuanDavid:シャットルは '.read()'呼び出しを他のファイルオブジェクトの '.write()'呼び出しで使用するため、読み込みデータを一方から他方に渡します。片方がバイナリモードで開いていて、もう片方がテキストであれば、互換性のないデータ(バイナリデータをテキストファイルに、テキストデータをバイナリファイルに渡しています)を渡しています。 –

    0

    あなたが反復処理することができます私はデータをコピーする

    with open(fname, 'r') as readfile: 
        for line in readfile: 
         outfile.write(line) 
    
    1

    多くの変数を使用する必要はありません。

    with open(outfilename, 'w') as outfile: 
        for fname in filenames: 
         with open(fname, 'r') as readfile: 
          outfile.write(readfile.read() + "\n\n") 
    
    1

    fileinputモジュールは、複数のファイルのPython 2.7を使用して

    for line in fileinput.input(glob.glob("*.txt")): 
        outfile.write(line) 
    
    +0

    これは、一度に1行ずつ読むことに限定されていないと、さらに優れています。 – Marcin

    +0

    @Marcin、それは正しいです。私はMartijn Pieterの 'shutil.copyfileobj' humdingerを見るまで、これはクールな解決策だと思っていました。興味深いもの: – iruvar

    1

    を反復処理する自然な方法を提供し、私は

    shutil.copyfileobj(readfile, outfile) 
    

    outfile.write(infile.read()) 
    

    のいくつかの "ベンチマーク" のテストを行いました

    私はサイズが63MBから313MBまでの20の.txtファイルを、2.6GBまでのジョイントファイルサイズで繰り返しました。どちらの方法でも、通常の読み取りモードはバイナリ読み取りモードよりも優れており、shutil.copyfileobjはoutfile.writeよりも一般的に高速でした。

    最高の組み合わせと、最悪の組み合わせ(outfile.write、バイナリモード)(shutil.copyfileobj、通常の読み出しモード)を比較すると、差は非常に有意であった

    outfile.write, binary mode: 43 seconds, on average. 
    
    shutil.copyfileobj, normal mode: 27 seconds, on average. 
    

    がOUTFILEが最終的な大きさを持っていました通常の読み取りモードでは2620 MB、バイナリ読み取りモードでは2578 MBです。

    +0

    それはどんなプラットフォームですか? – ellockie

    +0

    私はLinux Fedora 16、異なるノード、またはインテルCore 2 Quad CPU Q9550(2.83 GHz)を搭載したWindows 7 Enterprise SP1の2つのプラットフォームで動作します。私はそれが後者だと思う。 –

    +0

    情報ありがとう! – ellockie

    関連する問題