使用例: 1 週間分の数 GB のログ ファイルがあり、たとえば を使用して土曜日に発生した何かを検索する必要がありますgrep
。推測すると、ファイルの途中から検索を開始すると、処理時間が半分以上短縮され (ファイルの残り全体を処理する必要がないため)、関連データがスキップされないと想定されます。これは可能ですか?
答え1
データが時系列順に並んでいると仮定します。
- 末尾までシークして、次のように実行してファイルのサイズを取得します
ftell()
。 - その結果を2で割ります。
fseek()
その場所を探すために使用します。getline()
一度呼び出すと次の行の先頭に移動します。strptime()
現在何日であるかを確認するために使用します。- バイナリ検索を実行し、必要な行が見つかるまで手順 4 と 5 を繰り返します。
答え2
dd
次のようなものを使用できます:
dd if=log skip=xK bs=1M
これは、サイズが 1M (2^20) の x * 1024 ブロックをスキップします。dd(1)
単位の処理の詳細については、を参照してください。
バイナリ検索を自動化したい場合は、ログが通常の形式であれば、<date> [data]
出力をパイプすることができますhead -n 2
。2番行 (「通常」長い行という合理的な仮定の下では、完全な行になります) を選択し、必要な半分を決定します。
答え3
ファイル サイズを取得して 2 で割ります。それを 1024 で割ると KiB になります。(または 1024*1024 で MiB などになります。)
((fs = $(stat -c %s logfile) / 2 / 1024))
スキップして検索
dd if=logfile bs=1024 skip=$fs | grep blahblah
ログファイルがとてもcount=
に値を追加することで、1 日あたりのデータ量と一致しますdd
。
((cnt = $(stat -c %s logfile) / 5 / 1024))
dd if=logfile bs=1024 skip=$fs count=$cnt | grep blahblah
これにより、cnt * 1024
オフセット バイトのデータのバイトがパイプされますfs * 1024
。
すべてをスクリプトにラップし、スクリプトの外部で grep、一時ファイルなど、必要なものにパイプします。
答え4
あなたが具体的に何をしたいのか、そして私の「プロセス」が何を意味するのか、あまり明確ではありません。大きなファイルの場合、私のお気に入りの対話型プログラムは ですless
。これは大きなファイルを問題なく処理します。また、 を使用して、特定のパーセンテージにスキップすることもできます30%
。さらに、/
と を使用して検索することもできます?
。