바이너리로 여러 문자열 패치

바이너리로 여러 문자열 패치

바이너리 파일 형식(이러한 파일의 인스턴스가 많음)이 있고 "DC-GX850" 문자열을 "DMC-GX95"로 바꾸고 싶습니다. 다행히 두 문자열의 길이는 동일합니다. 파일 크기는 22MB일 수 있습니다. 일반적으로 이 문자열은 파일에 두 번 나타납니다(처음 1000바이트 내에서). 둘 다 교체해야 합니다.

내 운영 체제는 표준 BASH를 실행하는 MacOS 10.14.6입니다.

솔루션의 두 부분이 있지만 이를 결합할 수는 없습니다. 내 테스트 사례의 경우 소스 파일은 P1000047D.RW2이고 수정된 파일은 P1000047D.RW2입니다. "44434d2d47583835"는 "DMC-GX95"의 16진수 표현이고 10f0은 해당 파일 인스턴스에 대한 문자열의 시작입니다. ; 다른 파일은 다른 오프셋을 가질 수 있습니다.

이 코드는 파일을 올바르게 패치합니다.

echo "3a4: 44434d2d47583835" | xxd  -r - P1000047D.RW2
echo "10f0: 44434d2d47583835" | xxd  -r - P1000047D.RW2

이 코드는 패치에 필요한 두 개의 문자열을 생성합니다.

strings -t x P1000047.RW2 | grep "DC-GX850" | sed s/\ DC-GX850/:\ 44434d2d47583835/

결과:

3a4: 44434d2d47583835
10f0: 44434d2d47583835

그런데 이 둘을 결합하려고 하면 이 코드는 첫 번째 패치만 실행합니다.

strings -t x P1000047.RW2 | grep "DC-GX850" | sed s/\ DC-GX850/:\ 44434d2d47583835/ | xxd  -r - P1000047D.RW2

sed와 -n 옵션을 사용해 보았지만 여전히 작동하지 않습니다.

물론 스크립트를 루프로 작성할 수도 있지만 가능하다면 그렇게 하지 않는 것이 좋습니다. 어떤 제안이 있으십니까?

답변1

perl바이너리 파일을 쉽게 처리하려면 다음을 사용하세요 .

perl -pi -e 's/DC-GX850/DMC-GX95/g' ./*.RW2

또는 파일의 처음 1000바이트만 바꾸려는 경우:

perl -pi -e '
  BEGIN {$/ = \1000} # records are 1000 byte blocks instead of lines
  s/DC-GX850/DMC-GX95/g if $. == 1; # substitute in first record only
  close ARGV if eof # to reset $. between files' ./*.RW2

를 사용하면 -i파일이 그 자리에서 수정되고(사실상 수정된 복사본으로 대체됨) -i.orig확장자가 .orig.

관련 정보