주소, 바이트 값 및 주석이 포함된 텍스트 파일을 바이너리 파일로 구문 분석합니다.

주소, 바이트 값 및 주석이 포함된 텍스트 파일을 바이너리 파일로 구문 분석합니다.

다음 형식의 파일로 시작하려고 합니다.

00: 42 ; byte 0 is 0x42 / d
01: 52 ; byte 1 is 0x52 / r
02: 62 ; byte 2 is 0x62 / D
03: 72 ; byte 3 is 0x72 / R
07: 1f ; bytes 03..0e are implicitly 00, byte 0f is 0x1f

이를 사용하여 다음 값(16진수 형식)으로 8바이트 파일을 생성합니다.

42 52 62 72 00 00 00 1f

정확한 입력 형식은 고정되어 있지 않습니다. 나는 단일 문자이고 명확하기 때문에 주석 구분 기호로 ";"을 선택했습니다. 전통적으로 offset: 및 두 자리 16진수 값 형식이 분명해 보입니다.

나는 궁극적인 해결책이 주석을 사용 sed하거나 awk제거한 다음 출력을 파이핑하는 것을 포함한다고 생각 xxd하지만 지금까지 첫 번째 실험은 실패했으며 최상의 시나리오인 간단한 텍스트 파일을 구문 분석하기 위해 xxd를 얻을 수도 없습니다.


첫 번째 시도에서는 config.src를 단순화했습니다.

00: 42
01: 52
02: 62
03: 72

(지금은 주석과 암시적 0바이트를 생략하고 인쇄 가능한 ASCII에 해당하는 값을 고수합니다)

...그런 다음 바이너리를 생성해 보세요.

xxd -r config.src config.bin

cat config.bin내가 에서 무엇을 볼 것으로 기대합니까 xxd config.bin?

BRbr그리고00000000: 42 52 62 72 BRbr

내가 끝내는 것은 다음과 같습니다.

인쇄할 수 없는 콘텐츠가 포함된 2바이트 파일은 cat다음 출력으로 렌더링할 수 없습니다 xxd config.bin.00000000: 0301

그럼... 질문 #1...내가 xxd한테 무슨 잘못을 한 거지?, 어떻게 해결할 수 있나요(또는 더 좋은 방법이 있나요)? 나는 각 행에 바이트 값을 지정하고 연속된 값을 자동으로 건너뛰고 자동으로 0으로 채울 수 있기를 원한다는 점을 명심하세요.

질문 #2... xxd가 내 파일을 분석한 후에 어떻게 주석을 추가하고 xxd가 보기 전에 제거할 수 있습니까?

xxd 자체를 사용할 생각은 없습니다... 하지만 이것은 공유 네트워크 서버이고 루트 또는 관리자 액세스 권한이 없으므로 이는 apt-get install옵션이 아니며 소스에서 내 복사본을 컴파일하는 것은 불가능합니다. 반드시 매우 쉬운 것은 아닙니다).


(배경 정보...문제를 해결하는 데 필요하지는 않지만 이 작업을 수행하는 이유를 설명하기 위해 추가할 수 있습니다)

Arduino 기반 IoT 컨트롤러를 개발 중입니다. 지난 몇 주 동안 그 구성은 하드 코딩된 값과 며칠마다 용도를 변경하는 DIP 스위치의 다양한 해석으로 구성되었습니다. 점점 지루해지고 있어요. 아직 적절한 UI를 구현할 기분이 아니었기 때문에 시작 시 첫 번째 작업으로 웹 서버에서 바이너리 구성 blob을 char[]로 가져오도록 하는 방법을 생각했습니다(런타임 구성 값을 조정할 수 있음). ​보드 자체를 새로 고칠 필요 없이 이 시점에서 정말 고통스럽습니다.)

답변1

당신의 것부터 시작합시다 config.src:

$ cat config.src
00: 42 ; byte 0 is 0x42 / d
01: 52 ; byte 1 is 0x52 / r
02: 62 ; byte 2 is 0x62 / D
03: 72 ; byte 3 is 0x72 / R
07: 1f ; bytes 03..0e are implicitly 00, byte 0f is 0x1f

이것을 로 변환하면 config.bin주석을 건너뜁니다 -c1.

$ xxd -r -c1 config.src config.bin
$ xxd config.bin
00000000: 4252 6272 0000 001f                      BRbr....

다음 config.src형식으로 다시 변환합니다.

$ xxd -c1 config.bin # this is unmodified
00000000: 42  B
00000001: 52  R
00000002: 62  b
00000003: 72  r
00000004: 00  .
00000005: 00  .
00000006: 00  .
00000007: 1f  .
$ xxd -c1 config.bin | awk -F '' '
  {
    $0=substr($0, 7)    # remove 6 leading characters
    $0=substr($0, 1, 6) # remove ASCII output
  }
  /00$/{ next }      # skip hex 00
  { print $0 " ; " } # print line and empty comment
'
00: 42 ;
01: 52 ;
02: 62 ;
03: 72 ;
07: 1f ;

답변2

Perl의 기능을 시험해보고 싶을 수도 있습니다 pack.

전임자. 주어진

$ cat config.src
00: 42 ; byte 0 is 0x42 / d
01: 52 ; byte 1 is 0x52 / r
02: 62 ; byte 2 is 0x62 / D
03: 72 ; byte 3 is 0x72 / R
07: 1f ; bytes 03..0e are implicitly 00, byte 0f is 0x1f

그 다음에

$ perl -ne 'm/(\d+): ([[:xdigit:]]{2})/; while($n++ < $1){print pack("x")}; print pack("H*",$2)' config.src | xxd -c1
00000000: 42  B
00000001: 52  R
00000002: 62  b
00000003: 72  r
00000004: 00  .
00000005: 00  .
00000006: 00  .
00000007: 1f  .

관련 정보