![#1](https://linux55.com/image/67813/%231.png)
xxd -ps
16진수 형식으로 보고 있는 이진 데이터가 있습니다 . 구분 기호가 있는 두 헤더 사이의 바이트 거리는 48300 (=805*60) bytes 입니다 fafafafa
. 파일의 시작 부분을 건너뛰어야 합니다.
fafafafa 헤더 사이에 48300바이트가 있는 16진수 데이터의 예를 얻을 수 있습니다.여기라고데이터2015.6.26.txt이 헤더 중 3개와 거의 동등한 바이너리여기라고test_27.6.2015.bin처음 두 개의 헤더만 있습니다. 두 파일 모두에서 마지막 헤더의 데이터는 전체 길이가 아닙니다. 그렇지 않으면 바이트 오프셋, 즉 헤더 사이의 데이터 길이가 고정되어 있다고 가정할 수 있습니다.
알고리즘 의사코드
- 제목이 끝나는 곳을 확인하세요.
- 처음 두 개의 제목 위치를 보고 해당 위치 간의 차이를 설정합니다(d2-d1) 이벤트 간의 거리는 고정되어 있습니다(777).
- 바이트 위치별로 데이터 분할(777) - TODO 바이너리 형식으로 분할해야 합니까, 아니면
xxd -ps
변환된 데이터를 분할해야 합니까? 바이트 위치별(777)
xxd -r
비슷한 방법으로 데이터를 다시 바이너리로 변환할 수 있지만 xxd -ps | split and store | xxd -r
이것이 필요한지는 아직 확실하지 않습니다.
어느 단계에서 이진 데이터를 분할할 수 있나요? xxd -ps
변환된 형식 또는 바이너리 데이터 만 사용됩니다.
변환된 형식으로 분할하는 경우 xxd -ps
for 루프가 파일을 반복하는 유일한 방법이라고 생각합니다. 가능한 분할 도구 csplit
, split
..., 확실하지 않습니다. 그러나 확실하지 않습니다.
grep(ggrep은 gnu grep임) 16진수 데이터 출력
$ xxd -ps r328.raw | ggrep -b -a -o -P 'fafa' | head
49393:fafa
49397:fafa
98502:fafa
98506:fafa
147611:fafa
147615:fafa
196720:fafa
196725:fafa
245830:fafa
245834:fafa
바이너리 파일에서 유사한 grep을 실행하면 빈 줄만 출력됩니다.
$ ggrep -b -a -o '\xfa' r328.raw
문서
나에게 맞는 문서를 찾았습니다여기다음 그림은 일반적인 SRS 데이터 형식입니다.
어느 단계에서 이진 데이터를 분할할 수 있습니까(이진 데이터 또는 xxd -ps
변환된 데이터로)?
답변1
xxd를 거치지 않고도 바이너리 파일을 조작할 수 있습니다. 나는 xxd를 통해 당신의 데이터를 다시 실행하고 그것을 사용하여 grep -b
나에게 보여주었습니다.바이트 오프셋\xfa
바이너리 파일의 패턴(16진수에서 문자로 변환)
sed
출력에서 일치하는 문자를 제거하고 숫자만 남겼습니다 . 그런 다음 쉘 위치 인수를 결과 오프셋( set --
...) 으로 설정합니다.
xxd -r -p <data26.6.2015.txt >/tmp/f1
set -- $(grep -b -a -o -P '\xfa\xfa\xfa\xfa' /tmp/f1 | sed 's/:.*//')
이제 $1, $2, ...에 오프셋 목록이 있습니다. 그런 다음 dd를 사용하여 관심 있는 부분을 추출하고 블록 크기를 1( bs=1
)로 설정하여 바이트 단위로 읽을 수 있습니다. skip=
입력에서 건너뛸 바이트 수와 count=
복사할 바이트 수를 나타냅니다.
start=$1 end=$2
let count=$end-$start
dd bs=1 count=$count skip=$start </tmp/f1 >/tmp/f2
위 내용은 첫 번째 패턴의 시작 부분부터 두 번째 패턴 이전까지 추출됩니다. 패턴을 포함하지 않으려면 처음에 4를 추가하면 됩니다(갯수는 4씩 줄어듭니다).
모든 부분을 추출하려면 동일한 코드의 루프를 사용하고 시작 오프셋 0과 끝 오프셋 파일 크기를 숫자 목록에 추가하십시오.
xxd -r -p <data26.6.2015.txt >/tmp/f1
size=$(stat -c '%s' /tmp/f1)
set -- 0 $(grep -b -a -o -P '\xfa\xfa\xfa\xfa' /tmp/f1 | sed 's/:.*//') $size
i=2
while [ $# -ge 2 ]
do start=$1 end=$2
let count=$end-$start
dd bs=1 count=$count skip=$start </tmp/f1 >/tmp/f$i
let i=i+1
shift
done
grep이 이진 데이터를 처리할 수 없는 경우 xxd를 사용하여 데이터를 16진수 덤프할 수 있습니다. 먼저 모든 줄 바꿈을 제거하여 하나의 큰 줄을 얻은 다음 이스케이프되지 않은 16진수 값으로 grep을 수행한 다음 모든 오프셋을 2로 나누고 원본 파일에 dd를 수행합니다.
xxd -r -p <data26.6.2015.txt >r328.raw
tr -d '\n' <data26.6.2015.txt >f1
let size2=2*$(stat -c '%s' f1)
set -- 0 $(grep -b -a -o -P 'fafafafa' f1 | sed 's/:.*//') $size2
i=2
while [ $# -ge 2 ]
do let start=$1/2
let end=$2/2
let count=$end-$start
dd bs=1 count=$count skip=$start <r328.raw >f$i
let i=i+1
shift
done
답변2
대단한 뮤로 출력해답변그 사람은 데이터를 어디에 사용하나요?데이터2015.6.26.txt.
#1
$ cat 27.6.2015_1.sh && sh 27.6.2015_1.sh
xxd -r -p <data26.6.2015.txt >/tmp/f1
size=$(stat -c '%s' /tmp/f1)
pat=$(echo -e '\xfa\xfa\xfa\xfa')
set -- 0 $(ggrep -b -a -o "$pat" /tmp/f1 | sed 's/:.*//') $size
i=2
while [ $# -ge 2 ]
do start=$1 end=$2
let count=$end-$start
dd bs=1 count=$count skip=$start </tmp/f1 >/tmp/f$i
let i=i+1
shift
done
72900+0 records in
72900+0 records out
72900 bytes (73 kB) copied, 0.160722 s, 454 kB/s
#2
$ cat 27.6.2015_2.sh && sh 27.6.2015_2.sh
xxd -r -p <data26.6.2015.txt >/tmp/f1
size=$(stat -c '%s' /tmp/f1)
set -- 0 $(ggrep -b -a -o -P '\xfa\xfa\xfa\xfa' /tmp/f1 | sed 's/:.*//') $size
i=2
while [ $# -ge 2 ]
do start=$1 end=$2
let count=$end-$start
dd bs=1 count=$count skip=$start </tmp/f1 >/tmp/f$i
let i=i+1
shift
done
72900+0 records in
72900+0 records out
72900 bytes (73 kB) copied, 0.147935 s, 493 kB/s
#삼
$ cat 27.6.2015_3.sh && sh 27.6.2015_3.sh
xxd -r -p <data26.6.2015.txt >r328.raw
tr -d '\n' <data26.6.2015.txt >f1
let size2=2*$(stat -c '%s' f1)
set -- 0 $(ggrep -b -a -o -P 'fafafafa' f1 | sed 's/:.*//') $size2
i=2
while [ $# -ge 2 ]
do let start=$1/2
let end=$2/2
let count=$end-$start
dd bs=1 count=$count skip=$start <r328.raw >f$i
let i=i+1
shift
done
24292+0 records in
24292+0 records out
24292 bytes (24 kB) copied, 0.088345 s, 275 kB/s
24152+0 records in
24152+0 records out
24152 bytes (24 kB) copied, 0.061246 s, 394 kB/s
24152+0 records in
24152+0 records out
24152 bytes (24 kB) copied, 0.058611 s, 412 kB/s
304+0 records in
304+0 records out
304 bytes (304 B) copied, 0.001239 s, 245 kB/s
출력은 16진수 파일 1개와 바이너리 파일 4개입니다.
$ less f1
$ less f2
"f2" may be a binary file. See it anyway?
$ less f3
"f3" may be a binary file. See it anyway?
$ less f4
"f4" may be a binary file. See it anyway?
$ less f5
"f5" may be a binary file. See it anyway?
data26.6.2015.txt 파일에 3개의 헤더만 제공했기 때문에 fafafafa가 포함된 파일은 3개만 있어야 합니다. 여기서 마지막 헤더의 내용은 스텁입니다. f2-f5의 출력:
$ xxd -ps f2 |head -n3
48000000fe5a1eda480000000d00030001000000cd010000010000000000
000000000000000000000000000000000000000000000100000001000000
ffffffff57ea5e5580510b0048000000fe5a1eda480000000d0003000100
$ xxd -ps f3 |head -n3
fafafafa585e0000fe5a1eda480000000d00030007000000cd0100000200
000000000000020000000000008000000000000000000000000000000000
01000000ffffffff72ea5e55b2eb0900105e000016000000010000000000
$ xxd -ps f4 |head -n3
fafafafa585e0000fe5a1eda480000000d00030007000000cd0100000300
000000000000020000000000008000000000000000000000000000000000
01000000ffffffff72ea5e55f2ef0900105e000016000000010000000000
$ xxd -ps f5 |head -n3
fafafafa585e0000fe5a1eda480000000d00030007000000cd0100000400
000000000000020000000000008000000000000000000000000000000000
01000000ffffffff72ea5e55a9f10900105e000016000000010000000000
어디
- f1은 전체 데이터 파일입니다.데이터2015.6.26.txt(포함할 필요는 없습니다)
- f2는 파일 헤더, 즉 파일의 시작 부분입니다.데이터2015.6.26.txt첫 번째 타이틀까지머리털 머리머리(포함할 필요는 없습니다)
- f3이 첫 번째 헤더입니다. 맞습니다!
- f4는 두 번째 헤더입니다. 맞습니다!
- f5는 세 번째 헤더입니다. 맞습니다!
답변3
어렵지 않습니다. 시작 문자열을 찾아서 이름을 지정하고 후행 문자열을 일치시키면 됩니다. 그렇지 않다면 적어도 가까이 다가가려고 노력하십시오. 실제로 모든 16진수가 필요하지는 않지만 다음과 같이 사용하십시오.
fold -w2 <hexfile |
sed -e:t -e's/[[:xdigit:]]\{2\}$/\\x&/
/f[af]$/N;/\(.\)..\1$/!s/.*\n/&\\x/;t
/^.*\(.\)\(\n.*\)\n\(.*\n\).*/!bt
s//\3\3\3 H_E_A_D \1 E_N_D \2\2\2/
s/.* f//;s/a E.*//'
\x
이렇게 하면 각 바이트에 대해 한 줄에 하나의 16진수 바이트코드가 표시됩니다(접두사가 붙음).hexfile
와는 별개로바이트코드는 순서대로 4번 fa
나타납니다 . ff
이 경우에는H_E_A_D
또는E_N_D
대신 위치를 표시하세요.H_E_A_D
string은 네 개의 문자열 중 마지막 문자열을 대체합니다 \xfa
.E_N_D
string은 4개의 연속 문자열 중 첫 번째 문자열을 대체합니다 \xff
. 이는 또한 줄 번호별로 바이트 오프셋을 동기화 상태로 유지해야 합니다.
이와 같이:
PIPELINE | grep -C8n _
산출:
(살짝 다듬어주세요)
72596-\x8b 72597-\xfa 72598-\xfa 72599-\xfa 72600:H_E_A_D 72601-\x58 -- 72660-\x00 72661:E_N_D 72662-\xff 72663-\xff 72664-\xff 72665-\x72
따라서 위 명령의 출력을 다음과 같이 파이프할 수 있습니다.
fold ... | sed ... | grep -n _
...헤더가 시작하고 끝날 수 있는 오프셋 목록을 가져옵니다. GNU의 경우 fter 스위치를 grep
사용하여 -A
컨텍스트 시퀀스에서 보고 싶은 바이트 수를 알려줄 수 있습니다. 예를 들어 -A777
. 다음과 같은 출력을 얻고 전달할 수 있습니다.
... | grep -A777 E_N_D | sed -ne's/\\/&&/p' | xargs printf %b
...각 시퀀스에 대해 각 이진 바이트를 재생하며 일치 번호는 로 지정할 수 있습니다 -m[num]
.