복사하지 않고 바이너리 파일의 일부를 삭제하는 방법

복사하지 않고 바이너리 파일의 일부를 삭제하는 방법

6MB 파일의 처음 2바이트를 삭제해야 합니다. 그러나 이는 RAM이 32MB에 불과하고 사용 가능한 플래시 메모리가 1MB 미만인 임베디드 Linux입니다.

다음과 같이 dd를 사용해 보았습니다.

1 - #dd bs=1 skip=2 count=1022 if=input of=ouput_1

2 - #dd bs=1024 skip=1 if=input of=ouput_2

삼-#rm -rf input

4-#(dd if=ouput_1 ; dd if=ouput_2) > ouput

5-#rm -rf ouput_1 ouput_2

/tmp(RAM에 tmpfs로 마운트됨) 아래의 모든 파일에 대해 내 문제는 라인 3과 5 이전에 필요한 메모리가 12MB(2x6MB)이고 프로세스가 때때로 "메모리 부족" 오류로 인해 실패한다는 것입니다.

파일 크기를 두 배로 할당하지 않고 처음 2바이트를 제거할 수 있는 방법이 있습니까? dd(또는 기타)를 사용하여 바이너리 파일을 "제자리"에서 잘라낼 수 있나요?

답변1

나는 이것이 효과가 있다고 생각합니다:

$   # Create test file
$ echo "Hello, World" > h.data
$
$   # Move contents up by 2 bytes
$   # Note if= and of= are the same for in-place editing
$ dd bs=2 if=h.data skip=1 seek=0 conv=notrunc of=h.data
5+1 records in
5+1 records out
11 bytes (11 B) copied, 0.000598796 s, 18.4 kB/s
$
$   # Note 11 bytes were moved above
$   # Truncate the file after byte 11
$ dd bs=11 if=h.data skip=1 seek=1 count=0 of=h.data
0+0 records in
0+0 records out
0 bytes (0 B) copied, 0.000338852 s, 0.0 kB/s
$
$   # Display edited file:
$ cat h.data
llo, World
$ 

이 모든 것을 스크립트로 감싸면 다음과 같은 결과가 나올 수 있습니다.

#!/bin/bash

size=$(stat -c %s "$2")
dd bs=$1 if="$2" skip=1 seek=0 conv=notrunc of="$2"
dd bs=$((size - $1)) if="$2" skip=1 seek=1 count=0 of="$2"

다음과 같이 호출하세요.

./truncstart.sh 2 file.dat

2처음부터 제거된 바이트 수는 어디에 있습니까?file.data


@Gilles가 지적했듯이 이 솔루션은 dd처리 중에 발생할 수 있는 예상치 못한 중단에 대해 강력하지 않습니다. 이 경우 파일이 손상됩니다.

답변2

@DigitalTrauma의 답변을 바탕으로 마침내 이것이 저에게 효과적이었습니다.

size=$(stat -c %s file)
dd bs=2 if=file skip=1 seek=0 conv=notrunc count=511 of=file
dd if=file ibs=1024 skip=1 of=file conv=notrunc obs=1022 seek=1
truncate file $(( size - 2 ))

처음 2바이트를 제거하려면 dd작업 속도를 높이기 위해 두 단계가 필요하며 이는 truncate파일의 마지막 몇 바이트를 자르기 위한 작은 유틸리티입니다.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>


int main(int argc, char **argv) 
{
    if (argc != 3 ) {
        printf ("Usage: %s <file> <bytes>\n", argv[0]);
        exit(1);
    }

    if (truncate(argv[1], atoi(argv[2]))) {
        printf (" Error ! \n");
        exit(1);
    }

    return(0);
}

관련 정보