我想找到 8 GB 日志(文本)中某处的日期。
我可以在某种程度上绕过完整的顺序读取,并首先对文件(大小)进行二进制分割,或者以某种方式导航文件系统inodes
(我知道非常很少),从每个分割点开始读取,直到找到合适的偏移量,从哪里开始文本搜索包含日期的行?
tail
最后一行的读取不使用正常的顺序读取,所以我想知道这个工具是否在 bash 中可用,或者我是否需要使用 Python 或 C/C++...但我对一个bash
选项特别感兴趣..
答案1
听起来你想要:
tail -c +1048576
或您想要跳过的任何字节数。加号告诉 tail 从文件的开头而不是结尾开始测量。如果您使用的是 GNU 版本的 tail,您可以将其写为:
tail -c +1M
要在剪切后获得固定数量的字节,而不是文件的所有其余部分,只需通过 head 进行管道传输:
tail -c +1048576 | head -c 1024
答案2
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 调整为您认为需要的值。
答案3
我会尝试类似的方法将日志拆分为 512MiB 块,以便更快地解析。
split <filename> -b 536870912
如果您正在查找该文件,则以下操作将起作用:
for file in x* ; do
echo $file
head -n 1 $file
done
使用该输出来确定要查找哪个文件来查找您的日期。
答案4
这是我的脚本,我正在寻找第一行,其中第一个字段与我的号码匹配。这些行根据第一个字段排序。我使用dd检查128K块的第一行,然后跳转到该块并执行搜索。文件超过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 更快并且 确认甚至更好