파일에 대한 바이트 오프셋이 있습니다.
이 바이트의 줄 번호를 제공하는 도구가 있습니까?
- 다음과 같이 0으로 시작하는 바이트 수 : 첫 번째 바이트는 0이 아니라 1입니다.
- 1로 시작하는 줄 번호
- 파일에는 일반 텍스트, “이진”얼룩, 멀티 바이트 문자 등이 포함될 수 있습니다. 그러나 관심있는 섹션 : 파일 끝, ASCII 만 있습니다.
예를 들어, 파일 :
001
002
003 <<-- first zero on this line is byte 8
004
바이트 오프셋 8
이 있으면 줄을 줄 것 3
입니다.
줄 번호를 찾기 위해 다음과 같은 것을 사용할 수 있다고 생각합니다.
ㅏ. tail -c+(offset + 1) file | wc -l
여기 +1
로 tail
(1)에서 카운트
나. wc -l file
씨. 그런 tail -n+num
곳 num
입니다a - b + 1
그러나 … 나를 num
직접 줄 수있는 상당히 일반적인 도구가 있습니까?
편집, 오류 : 또는 더 명백한 :
head -c+offset file | wc -l
답변
귀하의 예에서
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의 “줄”은 항상 줄 바꿈으로 종료됩니다. 따라서 위의 명령은 12보다 작은 값 2
을 설정 하면 여전히 표시됩니다 b
(다음 줄 바꿈). 따라서 찾고있는 결과는 위의 파이프 라인 보고서 수에 1을 더한 값입니다.
이것은 분명히 파일의 바이너리 BLOB 부분에서 ASCII 텍스트 앞에 나오는 임의의 줄 바꿈을 계산합니다. 아스키 비트가 시작 위치를 알았다면, 당신은 추가 할 수 있습니다 skip="$offset"
받는 dd
명령 $offset
바이트의 수가 파일로 건너 뛸 수 있습니다.
답변
파이썬에서는 상당히 쉽게 수행 할 수 있지만 현재 이와 같은 전용 도구는 없습니다.
#!/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
이것은 매우 빠르고 간단한 스크립트입니다. 파일이 비어 있는지 확인하지 않으므로 비어 있지 않은 파일에서만 작동합니다.
답변
표시된 바이트 수를 추적하고 주어진 오프셋이 합계 내에 있어야 현재 행 번호를 내 보냅니다.
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;
답변
$perl -0nE 'say substr($_,0,8)=~ y/\n//' ex
2
perl -0nE exp
입력을 비방하고$_
exp를 실행substr(string,0,8)
처음 8 바이트를 선택합니다y/\n//
를 제거\n
하고 번호를 반환