データを手動で入力すると、複数の改行文字を含むレコードでデータベースが汚染されます。1 つの列のみを含む 60 GB の巨大なフラット ファイルで、先頭と末尾が二重引用符で区切られた適切なレコードの場合、次のように常に 1 行に収まる必要があります。
「多数のミトコンドリアゲノム、多くの原核生物ゲノム、およびいくつかの核ゲノムの完全な配列が現在利用可能です。」
不正なレコードの場合、次のように不特定多数の複数行にまたがります。
「現在の喫煙は、高リスクと強く逆相関していた。
付随するリスク要因を調整した後のパターン。
喫煙者と現在喫煙している人は、高リスクの
パターン。 "
これらの複数行のレコードは、UNIX コマンドによる下流のファイル分割を妨げますsplit
。split
は、これらの複数行を 1 つのレコードとしてインテリジェントに認識できず、1 つのレコードが別々のファイルに分割される可能性があります。 以下の 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);
この問題を解決して、出力ファイルが「クリーン」になり、処理可能な単一行レコードのみになるようにする便利な UNIX コマンドはありますかsplit
?
sed
オプションのように見えますが、次の投稿のどちらもこの質問に答えていません。
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
私のシステムでは、10 MB のファイルの場合 6 秒かかります。60 GB の場合は 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
が遅くなっています。ループはファイル全体を一度にメモリに読み込むため、ループを使用する必要があります。そのため、$count の印刷に非常に時間がかかります。for
while
for
perl -ne '
print,next if /^".*"$/m or /"$/m;
chomp, $_ .= <>, redo unless eof;
' gene.data