在 bash 中是否可以从任意字节计数偏移开始读取文件?

在 bash 中是否可以从任意字节计数偏移开始读取文件?

我想找到 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 更快并且 确认甚至更好

相关内容