14

かなり巨大なファイルをpostgresqlデータベースにロードしています。これを行うには、最初にファイルで使用splitして小さいファイル(それぞれ30Gb)を取得し、次にとを使用して小さいファイルをデータベースにロードしGNU Parallelますpsql copy

問題は、ファイルを分割するのに約7時間かかり、その後、コアごとにファイルのロードを開始することです。必要なのは、splitファイルの書き込みが完了するたびにファイル名をstd出力に出力するように指示する方法です。これにより、ファイルをパイプで送信し、書き込みが完了Parallelするとファイルのロードを開始します。splitこのようなもの:

split -l 50000000 2011.psv carga/2011_ | parallel ./carga_postgres.sh {}

マニュアルページを読みましたが、split何も見つかりません。splitまたは他のツールでこれを行う方法はありますか?

4

2 に答える 2

30

並列に分割を行うことができます:

<2011.psv parallel --pipe -N 50000000 ./carga_postgres.sh

--blockマンページではoverの使用が推奨されていることに注意してください。これにより、デフォルト-Nではレコード区切りで入力が分割されます。たとえば、次のようになります。\n

<2011.psv parallel --pipe --block 250M ./carga_postgres.sh

テスト--pipe-N

以下は、100 個の数字のシーケンスを 5 つのファイルに分割するテストです。

seq 100 | parallel --pipe -N23 'cat > /tmp/parallel_test_{#}'

チェック結果:

wc -l /tmp/parallel_test_[1-5]

出力:

 23 /tmp/parallel_test_1
 23 /tmp/parallel_test_2
 23 /tmp/parallel_test_3
 23 /tmp/parallel_test_4
  8 /tmp/parallel_test_5
100 total
于 2013-02-28T20:48:51.947 に答える
2

を使用する場合は、オプションGNU splitでこれを行うことができます--filter

'--filter=command'<br> このオプションを使用すると、単純に各出力ファイルに書き込むのではなく、出力ファイルごとに指定されたシェル コマンドにパイプ経由で書き込みます。コマンドは、コマンドの呼び出しごとに異なる出力ファイル名に設定される $FILE 環境変数を使用する必要があります。

ファイルを作成し、最後にバックグラウンドで carga_postgres.sh を起動するシェル スクリプトを作成できます。

#! /bin/sh

cat >$FILE
./carga_postgres.sh $FILE &

そのスクリプトをフィルターとして使用します

split -l 50000000 --filter=./filter.sh 2011.psv
于 2013-02-28T20:49:20.390 に答える