web-dev-qa-db-ja.com

巨大なテキストファイルで「head」または「tail」を使用-19GB

非常に大きなテキストファイルのチャンクの表示に問題があります。このファイルは約19GBですが、明らかに大きすぎて従来の方法では表示できません。

私が試してみました head 1およびtail 1head -n 1およびtail -n 1)両方のコマンドをさまざまな方法でパイプでつなぎます(途中でピースを取得するため)。 Ubuntu 9.10を実行しているLinuxマシンでこのファイルを処理できません。

このファイルをどのように処理しますか?私の最終的な目標は、行45000000と45000100に焦点を当てることです。

15
nicorellius

sedを使用する必要があります。

sed -n -e 45000000,45000100p -e 45000101q bigfile > savedlines

これは、sedに45000000-45000100行を含めて印刷し、45000101行で終了するように指示します。

12
Kyle Jones

単一のフィールドを持つ単一のテーブルを使用してMySQLデータベースを作成します。次に、ファイルをデータベースにインポートします。これにより、特定の行を非常に簡単に検索できます。

他に何も速くなるとは思えません(headtailがすでに失敗している場合)。結局、行nを見つけたいアプリケーションは、n改行が見つかるまでファイル全体を検索する必要があります。ある種のルックアップ(ファイルへのラインインデックスからバイトオフセット)がなければ、これ以上のパフォーマンスは達成できません。

MySQLデータベースを作成してデータをインポートするのがいかに簡単かを考えると、これは実行可能なアプローチだと思います。

これを行う方法は次のとおりです。

DROP DATABASE IF EXISTS helperDb;
CREATE DATABASE `helperDb`;
CREATE TABLE `helperDb`.`helperTable`( `lineIndex` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, `lineContent` MEDIUMTEXT , PRIMARY KEY (`lineIndex`) );
LOAD DATA INFILE '/tmp/my_large_file' INTO TABLE helperDb.helperTable (lineContent);
SELECT lineContent FROM helperTable WHERE ( lineIndex > 45000000 AND lineIndex < 45000100 );

/tmp/my_large_fileは、読み取りたいファイルです。

各行にタブ区切りの値を持つファイルをインポートするための正しい構文は次のとおりです。

LOAD DATA INFILE '/tmp/my_large_file' INTO TABLE helperDb.helperTable FIELDS TERMINATED BY '\n' (lineContent);

これのもう1つの大きな利点は、後で別の行のセットを抽出することにした場合、(もちろんデータベースを削除しない限り)処理を再度待つ必要がないことです。

4
Der Hochstapler

大きなファイル用の2つの古き良きツールは、joinsplitです。 split with --lines=<number>オプションを使用して、ファイルを特定のサイズの複数のファイルにカットできます。

たとえば、split --lines=45000000 huge_file.txt。結果のパーツはxa、xbなどになります。次に、パーツをheadすることができますxbこれには必要な行が含まれます。ファイルを「結合」して単一の大きなファイルに戻すこともできます。

1
Anssi

あなたは適切なツールを持っていますが、それらを誤って使用しています。以前のように 回答済み U&Lで、tail -n +X file | head -n Y+に注意)は、Xで始まるY行のsedよりも10〜15%高速です。 、exitのように、プロセスを明示的にsedする必要はありません。

tailは最初のX-1行を読み取って破棄し(それを回避する方法はありません)、次の行を読み取って出力します。 headは、要求された行数を読み取って出力し、終了します。ヘッドが終了すると、テールはSIGPIPE信号を受信して​​停止するため、入力ファイルからバッファーサイズに相当する(通常は数キロバイト)行を超えて読み取ることはありません。

0
Erich