dd – wie extrahiert man einen Unterabschnitt einer Datei mit 2 Offsets?

dd – wie extrahiert man einen Unterabschnitt einer Datei mit 2 Offsets?

Ich möchte eine Datei, bei der der Start-Byte-Offset 3020852 und der End-Byte-Offset 13973824 beträgt.

Es gibt eine Variante dieses Befehls, dd ibs=X obs=Y skip=1 count=1die bei mir noch nicht zum Laufen gekommen ist.

Antwort1

Es gibt mehrere Möglichkeiten, dies zu tun, wie Sie indiese ähnliche Frage. Ich gebe Ihnen den (meiner Meinung nach „idiomatischsten“) head | tailAnsatz und die ddHerangehensweise.

head --bytes=<end_offset> in_file.bin | tail --bytes=<end_offset - start_offset> > out_file.bin

Alternative:

dd bs=1 skip=<start_offset> count=<end_offset - start_offset> < in_file > out_file.bin

Antwort2

Mit Hilfe von @agtoever und @tom-yan ist dies der schnellste Weg, dies zu erreichen:

dd if=somefile of=somefile2 skip=$start_offset count=$(($end_offset-$start_offset)) iflag=skip_bytes,count_bytes

Ich habe es bsnicht angegeben, aber es kann beliebig eingestellt werden. Ein 1-MiB-BS ist eine gute Faustregel.

Danke.

Antwort3

Wenn vorhandene Tools versagen, schreiben Sie Ihr eigenes:

#!/usr/bin/env python
start, end = 3020852, 13973824
with open("input.bin", "rb") as inf:
    with open("output.bin", "wb") as outf:
        inf.seek(start)
        data = inf.read(end-start)
        outf.write(data)
        # just in case
        assert(inf.tell() == end)

Die Gesamtgröße ist nicht groß, daher wird der gesamte Block auf einmal in den RAM eingelesen. Wenn Sie mehrere GB blockweise kopieren möchten, können Sie dies folgendermaßen tun:

#!/usr/bin/env python
start = 3020852
end = 13973824
size = end - start
bs = 32 << 20   # (32 MB)
with open("input.bin", "rb") as inf:
    with open("output.bin", "wb") as outf:
        inf.seek(start)
        while size > 0:
            data = inf.read(min(size, bs))
            outf.write(data)
            size -= len(data)
        assert(inf.tell() == end)

verwandte Informationen