8 GBのログ(テキスト)のどこかにある日付を見つけたいのですが。
完全な順次読み取りをいくらかバイパスして、最初にファイル(サイズ)のバイナリ分割を行うか、何らかの方法でファイルシステムinodes
(これはveryについて少し知っている)をナビゲートして開始できますか?日付を含む行のテキスト検索を開始する場所からの適切なオフセットが見つかるまで、各分割ポイントから読み取りますか?
tail
の最後の行の読み取りは通常の順次読み取りを使用しないので、この機能が何らかの方法でbashで使用できるかどうか、またはPythonまたはCを使用する必要があるでしょうか?/C++ ...しかし、bash
オプションに特に興味があります。
for (( block = 0; block < 16; block += 1 ))
do
echo $block;
dd if=INPUTFILE skip=$((block*512))MB bs=64 count=1 status=noxfer 2> /dev/null | \
head -n 1
done
これは、一時分割ファイルを作成せず、ブロック* 512MBのデータを実行ごとにスキップし、その位置から64バイトを読み取り、出力をその64バイトの最初の行に制限します。
64を必要に応じて調整してください。
あなたが望むように聞こえます:
tail -c +1048576
またはスキップしたいバイト数。プラス記号は、末尾ではなくファイルの先頭から測定するようテールに指示します。 GNUテールのバージョンを使用している場合は、次のように記述できます。
tail -c +1M
ファイルの残りのすべてではなく、カット後に固定バイト数を取得するには、ファイルをヘッドにパイプします。
tail -c +1048576 | head -c 1024
このようなことを試して、ログを512MiBのチャンクに分割し、解析を高速化します。
split <filename> -b 536870912
あなたがファイルを探しているなら、以下はうまくいくでしょう:
for file in x* ; do
echo $file
head -n 1 $file
done
その出力を使用して、日付をgrepするファイルを決定します。
これが私のスクリプトです。最初のフィールドが私の番号と一致する場合、最初の行を探しています。行は最初のフィールドに従ってソートされます。 128Kのブロックの最初の行をチェックするためにddを使用し、次にブロックにジャンプして検索を実行します。ファイルが1Mを超えると効率が向上します。
コメントや修正は大歓迎です!
#!/bin/bash
search=$1;
f=$2;
bs=128;
max=$( echo $(du $f | cut -f1)" / $bs" | bc );
block=$max;
for i in $(seq 0 $max); do
n=$(dd bs=${bs}K skip=$i if=$f 2> /dev/null| head -2 | tail -1 | cut -f1)
if [ $n -gt $search ]; then
block=`expr $i - 1`
break;
fi
done;
dd bs=${bs}K skip=$block if=$f 2> /dev/null| tail -n +2 | awk -v search="$search" '$1==search{print;exit 1;};$1>search{exit 1;};';
*編集***grepははるかに高速で、 ack はさらに優れています