2011-12-15 6 views
4

> 4gbのファイルmyfile.gzを指定すると、Teradataの高速ロードで消費するためにパイプにzcatする必要があります。私はまた、ファイル内の行の数を数える必要があります。理想的には、ファイルを1回だけ通過させたいと思っています。私はawkを使ってstdoutに行全体($ 0)を出力し、awkのEND句を使って行数(awkのNR変数)を別のファイル記述子(outfile)に書き出します。ファイルの内容をパイプに送り、1行で#行を数える

私はawkを使ってこれを行うことができましたが、もっとpythonicな方法が存在するかどうかを知りたいと思います。

#!/usr/bin/env python 
from subprocess import Popen, PIPE 
from os import path 

the_file = "/path/to/file/myfile.gz" 

outfile = "/tmp/%s.count" % path.basename(the_file) 
cmd = ["-c",'zcat %s | awk \'{print $0} END {print NR > "%s"} \' ' % (the_file, outfile)] 
zcat_proc = Popen(cmd, stdout = PIPE, shell=True) 

パイプが後

"/dev/fd/" + str(zcat_proc.stdout.fileno()) 

これは動作しますが、私はその可能な場合のawkをスキップしてのpythonのより良い活用するために知りたいから読み込むのTeradataの高速読み込みの呼び出しによって消費され。私は他の方法にもオープンしています。私はこの方法で処理する必要がある複数の大きなファイルを持っています。

答えて

3

が行をカウントし、解凍しない、別のプロセスに渡すよう、

import gzip 

nlines = sum(1 for ln in gzip.open("/path/to/file/myfile.gz")) 

で行うことができますgzip - 圧縮されたファイルはPythonとその標準ライブラリで簡単に処理できます。

import gzip, subprocess, os 
fifo_path = "path/to/fastload-fifo" 
os.mkfifo(fifo_path) 
fastload_fifo = open(fifo_path) 
fastload = subprocess.Popen(["fastload", "--read-from", fifo_path], 
          stdin=subprocess.PIPE) 
with gzip.open("/path/to/file/myfile.gz") as f: 
    for i, line in enumerate(f): 
     fastload_fifo.write(line) 
    print "Number of lines", i + 1 
os.unlink(fifo_path) 

私はFastloadを呼び出す方法がわかりません - 呼び出しで正しいパラメータを代入してください。

+0

これはほぼそのまま動作しますが、Fastloadの実装の欠点の1つは、ファストロード制御ファイル自体が標準でなければならないということです。したがって、gunzipのデータは別のソースから取得する必要があります。シェルコマンドを呼び出さなくても、名前付きパイプをPythonで開く方法はありますか? –

+1

@NeilKodner:おそらく最も簡単な方法は、['os.mkfifo()'](http://docs.python.org/library/os.html#os.mkfifo)を使って名前付きパイプを作ることです。私は私の答えを更新します... –

7

zcatまたはAwkのいずれも必要ありません。あなたがラインで他に何かをしたい場合は、gzip圧縮されたファイル内の行をカウントすることは、このような

nlines = 0 
for ln in gzip.open("/path/to/file/myfile.gz"): 
    nlines += 1 
    # pass the line to the other process 
+0

とgzip.open()は、内容をRAMにロードするのではなく、各行を生成してファイルをインテリジェントに反復処理しますか? –

+0

@NeilKodner:はい、 'gzip.open'は、' zcat'のようにオンデマンドでファイルの一部を解凍します。 –

+0

Fastloadが読み込むパイプを作成するためにsubprocess.Popenを使用しますか、別の方法について説明しますか?私は/ dev/fd/nにgunzipされたデータを書く必要があります。以前は、awkコマンドはstdout = PIPEに、awk/zcatは実際のコマンドに書いていました。この場合、gzipされたファイルを反復処理するためにpythonを使用しているので、シェルコマンドはありません。 –

1

これはbashのの1つの単純なラインで行うことができます

zcat myfile.gz | tee >(wc -l >&2) | fastload 

これはstderrに行数を出力します。別の場所に置いておきたい場合は、wc出力をリダイレクトすることができます。

0

実際には、データをFastloadにパイプすることはできないはずです。そうすれば誰かが正確な例を投稿すれば素晴らしいでしょう。 FASTLOAD設定http://www.info.teradata.com/htmlpubs/DB_TTU_14_00/index.html#page/Load_and_Unload_Utilities/B035_2411_071A/2411Ch03.026.028.html#ww1938556

FILE =入力されたデータを含むデータ・ソースの名前を指定し、ファイル名 キーワードフレーズでのTeradataのドキュメントから

。 fileidは通常のファイルを参照する必要があります。 特に、パイプはに対応していません。