#1

#1

xxd -ps16진수 형식으로 보고 있는 이진 데이터가 있습니다 . 구분 기호가 있는 두 헤더 사이의 바이트 거리는 48300 (=805*60) bytes 입니다 fafafafa. 파일의 시작 부분을 건너뛰어야 합니다.

fafafafa 헤더 사이에 48300바이트가 있는 16진수 데이터의 예를 얻을 수 있습니다.여기라고데이터2015.6.26.txt이 헤더 중 3개와 거의 동등한 바이너리여기라고test_27.6.2015.bin처음 두 개의 헤더만 있습니다. 두 파일 모두에서 마지막 헤더의 데이터는 전체 길이가 아닙니다. 그렇지 않으면 바이트 오프셋, 즉 헤더 사이의 데이터 길이가 고정되어 있다고 가정할 수 있습니다.

알고리즘 의사코드

  1. 제목이 끝나는 곳을 확인하세요.
  2. 처음 두 개의 제목 위치를 보고 해당 위치 간의 차이를 설정합니다(d2-d1) 이벤트 간의 거리는 고정되어 있습니다(777).
  3. 바이트 위치별로 데이터 분할(777) - TODO 바이너리 형식으로 분할해야 합니까, 아니면 xxd -ps변환된 데이터를 분할해야 합니까? 바이트 위치별(777)

xxd -r비슷한 방법으로 데이터를 다시 바이너리로 변환할 수 있지만 xxd -ps | split and store | xxd -r이것이 필요한지는 아직 확실하지 않습니다.

어느 단계에서 이진 데이터를 분할할 수 있나요? xxd -ps변환된 형식 또는 바이너리 데이터 만 사용됩니다.

변환된 형식으로 분할하는 경우 xxd -psfor 루프가 파일을 반복하는 유일한 방법이라고 생각합니다. 가능한 분할 도구 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_Dstring은 네 개의 문자열 중 마지막 문자열을 대체합니다 \xfa.E_N_Dstring은 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].

관련 정보