binäre Datei bytes weise teilen, suche schnellere Variante

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
ren22

binäre Datei bytes weise teilen, suche schnellere Variante

Beitrag von ren22 » 14.09.2019 11:07:13

Hallo,

ich versuche eine binär Datei, genau genommen ein AVCHD Stream, zu splitten in viele kleine "Dateistückchen" alle paar bytes, dazu habe ich eine seperate Datei mit offsets
cat "tempvalues"

Code: Alles auswählen

0
1311
121899
125784
130213
...usw
zum aufteilen der Datei benutze ich folgenden Befehl, der aber scheinbar 1) die cpu auf 100% bringt und 2) langsam ist!

Code: Alles auswählen

dd if="$EINGABE_DATEI" of=$DATEI_SCHNITT skip="$OFFSET_OLD" bs=1 count="$BYTESTOWRITE"
und hier das Shellscript was die Arbeit macht:

Code: Alles auswählen

#!/bin/bash

FILE="00000.MTS"

echo "0" > tempvalues
cp -f "${FILE}-orig" "$FILE"
for VALUE in $(grep -aob "MDPM" "$FILE" | cut -d':' -f1); do
    VALUE=$((VALUE -16))
    echo "$VALUE" >> tempvalues
done
#set -x
# how many lines to parse *helper for the last bytes to write
READ_LINES="$(cat tempvalues | wc -l)"
# the size in bytes of the original file
FILE_SIZE_IN_BYTES="$(du -b $FILE | awk '{print $1}')"
# file part counter printf "%0*d\n" 5 $((00000+1))
CHUNK_COUNTER="0"
# old file offset
OFFSET_OLD="0"
# how much bytes in file parts toghter has been written
TOTAL_BYTES_WRITTEN="0"
# how much bytes are left for writing
BYTES_LEFT_TO_WRITE="0"
#set -x
while read OFFSET_CURRENT; do
    #skip first line
    #echo "READ_LINES: $READ_LINES"
    if [ $OFFSET_CURRENT -eq 0 ]; then
        OFFSET_OLD="$OFFSET_CURRENT"
        READ_LINES="$(($READ_LINES-1))"
        continue
    fi
    #if [ ! $OFFSET_CURRENT -eq 0 ]; then
    #    OFFSET_OLD="$(($OFFSET_OLD+1))"
    #fi
    echo "Writing from offset: $OFFSET_OLD -> $OFFSET_CURRENT"
    READ_LINES="$(($READ_LINES-1))"

    BYTESTOWRITE="$(($OFFSET_CURRENT - $OFFSET_OLD))"
    echo "bytestowrite: $BYTESTOWRITE"
    echo "skip=$OFFSET_OLD bs=1 count=$BYTESTOWRITE"
    dd if="$FILE" of="$(printf "%0*d\n" 32 $(($CHUNK_COUNTER+1)))" skip="$OFFSET_OLD" bs=1 count="$BYTESTOWRITE"
    #cat "$FILE" | dd of="$(printf "%0*d\n" 32 $(($CHUNK_COUNTER+1)))" skip="$OFFSET_OLD" bs=1 count="$BYTESTOWRITE"
    #wait && sync
    # +1 on CURRENT OFFSET cause write from 0-1311, then next chunk from 1312-nnnnn
    OFFSET_OLD="$(($OFFSET_CURRENT+0))"
    TOTAL_BYTES_WRITTEN="$(($TOTAL_BYTES_WRITTEN + $BYTESTOWRITE))"
    echo "TOTAL_BYTES_WRITTEN: $TOTAL_BYTES_WRITTEN"

    CHUNK_COUNTER="$(($CHUNK_COUNTER + 1))"
    echo "CHUNK_COUNTER: $CHUNK_COUNTER"

    BYTES_LEFT_TO_WRITE="$(($FILE_SIZE_IN_BYTES - $TOTAL_BYTES_WRITTEN))"
    echo "BYTES_LEFT_TO_WRITE: $BYTES_LEFT_TO_WRITE"
    echo "FILE_SIZE_IN_BYTES : $FILE_SIZE_IN_BYTES"
    echo

    # writes lates bytes of the orignal file
    if [ $READ_LINES -eq 0 ]; then
        echo "----"
        echo "Writing from offset: $TOTAL_BYTES_WRITTEN -> $FILE_SIZE_IN_BYTES"

    BYTESTOWRITE="$(($FILE_SIZE_IN_BYTES - $TOTAL_BYTES_WRITTEN))"
    echo "bytestowrite: $BYTESTOWRITE"

    echo "skip=$OFFSET_OLD bs=1 count=$BYTESTOWRITE"

    dd if="$FILE" of="$(printf "%0*d\n" 32 $(($CHUNK_COUNTER+1)))" skip="$OFFSET_OLD" bs=1 count="$BYTESTOWRITE"
    #cat "$FILE" | dd of="$(printf "%0*d\n" 32 $(($CHUNK_COUNTER+1)))" skip="$OFFSET_OLD" bs=1 count="$BYTESTOWRITE"
    #wait && sync
    # +1 on CURRENT OFFSET cause write from 0-1311, then next chunk from 1312-nnnnn
    #OFFSET_OLD="$(($OFFSET_CURRENT+0))"
    TOTAL_BYTES_WRITTEN="$(($TOTAL_BYTES_WRITTEN + $BYTESTOWRITE))"
    echo "TOTAL_BYTES_WRITTEN: $TOTAL_BYTES_WRITTEN"

    CHUNK_COUNTER="$(($CHUNK_COUNTER + 1))"
    echo "CHUNK_COUNTER: $CHUNK_COUNTER"

    BYTES_LEFT_TO_WRITE="$(($FILE_SIZE_IN_BYTES - $TOTAL_BYTES_WRITTEN))"
    echo "BYTES_LEFT_TO_WRITE: $BYTES_LEFT_TO_WRITE"
    echo "FILE_SIZE_IN_BYTES : $FILE_SIZE_IN_BYTES"
    echo

    fi
    #if [ $CHUNK_COUNTER -eq "2" ]; then
    #    exit 0
    #fi
done < tempvalues

[ -f tempvalues ] && rm -f tempvalues

Benutzeravatar
MSfree
Beiträge: 11604
Registriert: 25.09.2007 19:59:30

Re: binäre Datei bytes weise teilen, suche schnellere Variante

Beitrag von MSfree » 14.09.2019 11:15:32

ren22 hat geschrieben: ↑ zum Beitrag ↑
14.09.2019 11:07:13
zum aufteilen der Datei benutze ich folgenden Befehl, der aber scheinbar 1) die cpu auf 100% bringt und 2) langsam ist!

Code: Alles auswählen

dd if="$EINGABE_DATEI" of=$DATEI_SCHNITT skip="$OFFSET_OLD" bs=1 count="$BYTESTOWRITE"
bs=1 ist dein Problem. Es wäre sinnvoller, eine Blockgröße zu verwenden, die mindestens ein Vielfaches von 4kByte ist. Den count= muß man dann vorher rechnerisch ermitteln, sollte aber keine allzu größe Hürde sein. Die resultierenden Dateien werden dann allerdings etwas zu groß. Mit dem Befehl truncate kannst du im Nachgang die Dateigröße aber wieder auf das gewünschte Maß reduzieren.

ren22

Re: binäre Datei bytes weise teilen, suche schnellere Variante

Beitrag von ren22 » 14.09.2019 15:15:28

MSfree hat geschrieben: ↑ zum Beitrag ↑
14.09.2019 11:15:32
ren22 hat geschrieben: ↑ zum Beitrag ↑
14.09.2019 11:07:13
zum aufteilen der Datei benutze ich folgenden Befehl, der aber scheinbar 1) die cpu auf 100% bringt und 2) langsam ist!

Code: Alles auswählen

dd if="$EINGABE_DATEI" of=$DATEI_SCHNITT skip="$OFFSET_OLD" bs=1 count="$BYTESTOWRITE"
bs=1 ist dein Problem. Es wäre sinnvoller, eine Blockgröße zu verwenden, die mindestens ein Vielfaches von 4kByte ist. Den count= muß man dann vorher rechnerisch ermitteln, sollte aber keine allzu größe Hürde sein. Die resultierenden Dateien werden dann allerdings etwas zu groß. Mit dem Befehl truncate kannst du im Nachgang die Dateigröße aber wieder auf das gewünschte Maß reduzieren.
Danke für dein Tip, habe ich jetzt noch nicht getested aber mit doppelten Datei hin- und- her- schieben, ob das nicht länger dauert !?.. müsste ich mal testen..

alter nativ kann ich noch den codezeiler hier anbieten, geht schneller als die erste Methode;

Code: Alles auswählen

xxd -p -c 256 $FILE 2>/dev/null | tr -d '\n' 2>/dev/null | tail -c +$((($OFFSET_OLD*2)+1)) 2>/dev/null | head -c $(($BYTESTOWRITE*2)) | xxd -r -p > chunks/$(printf "    %0*d\n" 32 $(($CHUNK_COUNTER+1)))
sonst bin ich noch gerne offen für weitere Möglichkeiten.
Danke

Benutzeravatar
MSfree
Beiträge: 11604
Registriert: 25.09.2007 19:59:30

Re: binäre Datei bytes weise teilen, suche schnellere Variante

Beitrag von MSfree » 14.09.2019 15:44:40

ren22 hat geschrieben: ↑ zum Beitrag ↑
14.09.2019 15:15:28
Danke für dein Tip, habe ich jetzt noch nicht getested aber mit doppelten Datei hin- und- her- schieben, ob das nicht länger dauert !?.. müsste ich mal testen..
truncate schiebt keine Dateien hin oder her sondern setzt nur die logische Dateigröße im Dateisystem. Die Datei ansich bleibt auf der Platte an Ort und Stelle, so daß truncate eine sehr schnelle Operation ist.

Benutzeravatar
schorsch_76
Beiträge: 2597
Registriert: 06.11.2007 16:00:42
Lizenz eigener Beiträge: MIT Lizenz

Re: binäre Datei bytes weise teilen, suche schnellere Variante

Beitrag von schorsch_76 » 14.09.2019 16:11:16

split macht genau das was du willst.
😊

http://man7.org/linux/man-pages/man1/split.1.html

Antworten