時には、複数行にまたがるレコードに60GBのフラットファイルを分割します。

時には、複数行にまたがるレコードに60GBのフラットファイルを分割します。

データを手動で入力すると、複数行の改行を含むレコードでデータベースが汚染される可能性があります。単一の列を持つ巨大な60 GBのフラットファイルの先頭と末尾に二重引用符を付けた良いレコードの場合は、次のように常に1行で構成する必要があります。

「今、多くのミトコンドリア、多くの原核生物、およびいくつかの核ゲノムの完全な配列が利用可能です」。

無効なレコードの場合は、次のように無制限の複数行にまたがっています。

「現在の喫煙は、より高いリスクと強い反比例関係があります。

付随するリスク要因を調整した後のモデルです。ティーン

喫煙者、現在喫煙者は高リスクグループにかかる可能性が著しく低かった。

柄。 」

これらの複数行レコードは、UNIXコマンドがダウンストリームファイルの分割を防止しますsplitsplitこれらの複数の行を単一のレコードとしてインテリジェントに認識する方法がないため、単一のレコードを別々のファイルに分割することができます。以下のPerlは、この大きなファイルを分割する前に間違った行をマージするには遅すぎます。 2時間以上待ってからは$countを印刷できないからです。

$file=$ARGV[0];
open(INFO, $file) or die("Could not open $file.");
open(OUT, ">out") or die("Could not open $file.");

$mergedline = "";
$count=0;
foreach $line (<INFO>)  {
    print $count++;
    if ($line =~ /^".*"\n$/) {
                print OUT $line;
                $mergedline = "";
                next;
        } elsif ($line =~ /"\n$/) {
                print OUT $mergedline;
                $mergedline = "";
                next;
        } else {
                chomp $line;
                $mergedline .= $line;
        }
}
close(INFO);

出力ファイルが「クリーン」で1行のレコードのみを処理できるように、この問題を解決できる便利なUNIXコマンドはありますかsplit

sedオプションのように見えますが、次の投稿のどれも質問に答えません。

https://stackoverflow.com/questions/15758814/turning-multiple-lines-into-one-line-with-comma-separated-perl-sed-awk

https://stackoverflow.com/questions/11290616/sed-conditional-merge-of-multiple-lines

http://www.unix.com/shell-programming-and-scripting/80633-sed-combining-multiple-lines-into-one.html

投稿パターンが定期的すぎて一定であるからです。

答え1

sed分割線接続のみ

sed ':a
/".*"$/b
N;s/\n/ /;ba' input >> output

私のシステムは10MBファイルを処理するのに6秒かかります。 60GBの場合は10時間になります。

bbe少し速い

bbe -b '/"/:/"/' -o output -e 'y/\n/ /' input

しかし、まだ4秒かかります。

残念ながら、これらのスクリプト言語は非常に大きなファイルで正しく機能するツールではありません。小さなプログラムを書いてみてはいかがでしょうかC

答え2

使用例gawk:

awk 'BEGIN {RS = "\"\n"} {++n; print $0"\""> n".txt"}' input

inputこれは、任意の順序でファイルを分割し、改行"\n)を使用することを意味します。これは、引用符の直後にはない改行文字を無視するため、複数行のレコードが保存されます。この例では、出力はテキストファイルに書き込まれますが、その> n".txt"セクションを削除するとレコードをパイプに送信できます。

答え3

Perlループを使用してファイルを読み取るため、for速度が遅くなります。ループはファイル全体を一度にメモリにロードするwhileため、ループを使用する必要があります。forこれが$countを印刷するのに時間がかかる理由です。

perl -ne '
   print,next if /^".*"$/m or /"$/m;
   chomp, $_ .= <>, redo unless eof;
' gene.data

関連情報