コピーせずにバイナリファイルの一部を削除する方法

コピーせずにバイナリファイルの一部を削除する方法

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倍に割り当てずに最初の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作業を高速化するために2つのステップが必要です。これは、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);
}

関連情報