具有文件的字节偏移量。
有没有一个工具可以给出该字节的行号?
- 字节计数从零开始,如下所示:第一个字节是 0 而不是 1。
- 行号从 1 开始。
- 文件可以有纯文本、“二进制”blob、多字节字符等。但我感兴趣的部分:文件结尾,只有 ASCII。
示例,文件:
001
002
003 <<-- first zero on this line is byte 8
004
有字节偏移量8
会给我 line 3
。
我想我可以用这样的东西来查找行号:
A。tail -c+(offset + 1) file | wc -l
,此处从 1+1
开始tail
计数
。wc -l file
C。那么在tail -n+num
哪里num
a - b + 1
但是......有没有一个相当常见的工具可以num
直接给我?
编辑,错误:或更明显的:
head -c+offset file | wc -l
答案1
在你的例子中,
001
002
003
004
字节号 8 是第二个换行符,而不是0
下一行。
$b
以下将为您提供字节后的整行数:
$ dd if=data.in bs=1 count="$b" | wc -l
它将报告2
设置b
为 8,并将报告设置1
为b
7。
该dd
实用程序(按照此处使用的方式)将从文件中读取data.in
,并将读取$b
大小为 1 字节的块。
正如“icarus”在下面的评论中正确指出的那样,使用bs=1
效率很低。在这种特殊情况下,交换bs
和会更有效count
:
$ dd if=data.in bs="$b" count=1 | wc -l
这将与第一个命令具有相同的效果dd
,但只会读取一个$b
字节块。
该wc
实用程序对换行符进行计数,Unix 中的“行”始终以换行符结尾。因此,2
如果您设置b
为低于 12 的值(以下换行符),上面的命令仍然会显示。因此,您要查找的结果是上述管道报告的任何数字加 1。
显然,这也会计算文件中 ASCII 文本之前的二进制 blob 部分中的随机换行符。如果您知道 ASCII 位从哪里开始,则可以添加skip="$offset"
到dd
命令中,其中$offset
是要跳到文件中的字节数。
答案2
目前还没有这样的专用工具,尽管在 python 中可以相当容易地完成:
#!/usr/bin/env python3
import sys
import os
offset = int(sys.argv[2])
newline = 1
with open(sys.argv[1]) as fd:
fd.seek(offset)
while True:
try:
byte = fd.read(1)
if byte == '\n': newline+=1
#print(byte)
offset = offset - 1
fd.seek(offset)
except ValueError:
break
print(newline)
用法很简单:
line4byte.py <FILE> <BYTE>
测试运行:
$ cat input.txt
001
002
003
004
$ chmod +x ./line4byte.py
$ ./line4byte.py input.txt 8
3
这是一个非常快速且简单的脚本。它不会检查文件是否为空,因此它仅适用于非空文件。
答案3
如果给定的偏移量在总和之内,则跟踪看到的字节并发出当前行号:
perl -E '$off=shift;while(<>){$sum+=length;if($sum>=$off){say $.;exit}}' 8 file
或者详细地说:
#!/usr/bin/env perl
use strict;
use warnings;
die "Usage: $0 offset file|-\n" if @ARGV != 2;
my $offset = shift;
shift if $ARGV[0] eq '-';
my $sum;
while (readline) {
$sum += length;
if ($sum >= $offset) {
print "$.\n";
exit;
}
}
exit 1;
答案4
$perl -0nE 'say substr($_,0,8)=~ y/\n//' ex
2
perl -0nE exp
将输入吞入$_
并执行 expsubstr(string,0,8)
选择前 8 个字节y/\n//
删除\n
并返回其编号