"\x00" 바이트를 포함하는 바이너리 스트림 편집

"\x00" 바이트를 포함하는 바이너리 스트림 편집

셸 도구만 사용하여 NULL(0x00 문자)이 포함된 바이너리 스트림을 편집하고 출력 스트림에서 0x00 문자를 유지하려면 어떻게 해야 합니까?

편집하려면 아래와 같이 지정된 위치의 한 문자를 다른 문자(아래 예에서는 "|" 문자)로 바꿔야 합니다.

dd ibs=1 skip=$offset count=$reglen status=none if=$ARQ |
        sed 's/./\|/2' |
        sed 's/./\|/5' #| more replacements....

그러나 sed는 교체하기 전에 '\0x00' 문자를 모두 제거합니다.

편집 - @George Vasiliou의 테스트를 사용하여 내 환경에서 sed 동작을 보여줍니다.

$ echo -e "lineA\nlineB\nlineC" | tr '\n' '\0' | od -t x1
0000000 6c 69 6e 65 41 00 6c 69 6e 65 42 00 6c 69 6e 65
0000020 43 00
0000022

$ echo -e "lineA\nlineB\nlineC" | tr '\n' '\0' | sed 's/./|/5' | od -t x1
0000000 6c 69 6e 65 7c 6c 69 6e 65 42 6c 69 6e 65 43
0000017

내 환경은 AIX 7.1이고 sed에는 GNU 버전이 없습니다.

답변1

sed텍스트유용. 그것은 적용됩니다텍스트 라인(개행으로 구분된 NUL이 아닌 문자(바이트 아님)의 제한된 길이 시퀀스).

2 번째 5번째를 바꾸고 싶다면 바이트바이트 시퀀스이지만 여러 가지 이유로 작동하지 않습니다.

  • sed텍스트에 적용됩니다. 입력에 NUL 문자가 포함되어 있고, 줄 바꿈으로 끝나지 않고, 두 줄 바꿈 사이에 LINE_MAX 바이트 이상이 있고, 유효한 문자를 형성하지 않는 바이트 시퀀스가 ​​포함되어 있으면(구현에 따라) sed전혀 작동하지 않습니다. (GNU에는 sed이러한 제한 사항이 많지 않습니다.)
  • 해당 이진 입력이 유효한 텍스트를 형성하더라도 .바이트가 아닌 문자와 일치하므로 여러 바이트가 일치할 수 있습니다.
  • sed 코드는 각각에 대해 실행되기 때문에철사입력의 두 번째 및 다섯 번째 문자는 전체 입력의 두 번째 및 다섯 번째 문자가 아닌 각 줄의 두 번째 및 다섯 번째 문자를 변경합니다.

입력을 NUL 바이트 제한이나 길이 제한 없이 임의의 바이트 배열로 처리하려면 다음을 사용할 수 있습니다 perl.

 dd.... | perl -0777 -pe 'for $o (1, 4) {substr($_, $o, 1) = "|"}'

예:

$ printf 'a\0b\0cd' |
>   perl -0777 -pe 'for $o (1, 4) {substr($_, $o, 1) = "|"}' |
>   od -Ax -tx1 -tc
000000  61  7c  62  00  7c  64
         a   |   b  \0   |   d
000006

vim또는 도우미 를 사용하여 중간 텍스트 표현을 사용할 수 있습니다 xxd.

dd... | xxd -p | sed '1s/../7c/2;1s/../7c/5' | xxd -p -r

xxd -p기본적으로 16진수 덤프는 한 줄에 60자로 제공됩니다. 위에서 첫 번째 줄의 두 번째와 다섯 번째 2자리 16진수 숫자를 7cASCII 숫자로 대체했습니다 |.

답변2

노력하다베이베이, sed와 유사한 바이너리 스트림 편집기입니다.

매뉴얼 페이지

bbe는 sed와 유사한 바이너리 파일 편집기입니다. sed처럼 입력을 한 줄씩 읽는 대신 bbe는 입력 스트림에서 임의의 청크를 읽고 발견된 청크에 대해 바이트 종속 변환을 수행합니다.

답변3

확실합니까? 간단한 테스트로 볼 때 제 경우에는 이런 일이 발생하지 않는 것 같습니다(gnu sed 4.2.2).

$ echo -e "lineA\nlineB\nlineC"
lineA
lineB
lineC
$ echo -e "lineA\nlineB\nlineC" |tr '\n' '\0'
lineAlineBlineC
$ echo -e "lineA\nlineB\nlineC" |tr '\n' '\0' |sed 's/./|/5'
line|lineBlineC
# Verification if the nulls are still there:
$ echo -e "lineA\nlineB\nlineC" |tr '\n' '\0' |sed 's/./|/5' |tr '\0' '\n'                                                                                                
line|
lineB
lineC

추가 테스트 후 테스트에서 6번째 문자(빈 위치)를 바꾸면 null이 손실됩니다.

$ echo -e "lineA\nlineB\nlineC" |tr '\n' '\0' |sed 's/./|/6' |tr '\0' '\n'
lineA|lineB 
lineC

$ echo -e "lineA\nlineB\nlineC" |tr '\n' '\0' |sed 's/./|/7' |tr '\0' '\n'
lineA
|ineB           
lineC 

관련 정보