7

データのストリームをその STDOUT に出力するプログラム (gawk) があります。処理されるデータは文字通り数十 GB です。単一のファイルに保存するのではなく、チャンクに分割し、保存する前にそれぞれに追加の処理 (圧縮など) を適用する可能性があります。

私のデータは一連のレコードであり、分割によってレコードを半分に分割したくありません。各レコードは、次の正規表現に一致します。

^\{index.+?\}\}\n\{.+?\}$

または簡単にするために、2 つの行 (最初は奇数で、ストリームの先頭から数えた場合でも) は常にレコードを作成すると仮定できます。

できること:

  • 標準のLinuxコマンドを使用して、チャンクの適切なサイズを定義してSTDINを分割しますか? レコード変数のサイズが正確であることを保証できないため、正確である必要はありません。または、def の場合はレコード数のみ。サイズによっては不可能です
  • 各チャンクを圧縮してファイルに保存します (名前に 001、002 などの番号を付けます)。

GNU parallelのようなコマンドを認識したり、それらcsplitを組み合わせる方法がわかりません。上で説明した機能が、カスタム perl スクリプトを書かずに実現できれば素晴らしいでしょう。ただし、これは別の最後の手段になる可能性がありますが、最適な実装方法はわかりません。

4

2 に答える 2

8

GNU Parallel は stdin をレコードのチャンクに分割できます。これにより、標準入力が 50 MB のチャンクに分割され、各レコードが 2 行になります。各チャンクは gzip に渡され、[チャンク番号].gz という名前に圧縮されます。

cat big | parallel -l2 --pipe --block 50m gzip ">"{#}.gz

2 行目が '{index' で始まらないことがわかっている場合は、'{index' をレコードの開始として使用できます。

cat big | parallel --recstart '{index' --pipe --block 50m gzip ">"{#}.gz

次に、分割が正しく行われたかどうかを簡単にテストできます。

parallel zcat {} \| wc -l ::: *.gz

レコードがすべて同じ長さでない限り、異なる数の行が表示される可能性がありますが、すべて均等です。

簡単な紹介については、紹介ビデオをご覧ください: https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1

チュートリアルを実行します (man parallel_tutorial)。あなたのコマンドラインはあなたを気に入るはずです。

于 2014-03-25T08:26:02.463 に答える