UPDATE (im Nachhinein): ... Diese Frage / Antwort (meine Antwort) lässt mich an den Hund denken, der das Auto immer wieder verfolgt. Eines Tages holt er schließlich das Auto ein. Okay, er hat es verstanden, aber er kann wirklich nicht viel damit anfangen ... Dieser Anser "fängt" die Saiten, aber dann kann man nicht viel damit anfangen, wenn sie Null-Bytes eingebettet haben ... (also eine große +1 an Gilles Antwort .. hier ist möglicherweise eine andere Sprache in Ordnung.)
dd
Liest alle Daten ... Es wird mit Sicherheit nicht bei Null als "Länge" aufgehen ... aber wenn Sie \ x00 irgendwo in Ihren Daten haben, müssen Sie kreativ sein, wie Sie damit umgehen;dd
hat keine propblems damit, aber Ihr Shell-Skript wird Probleme haben (aber es hängt davon ab, was Sie mit den Daten tun möchten) ... Im Folgenden wird grundsätzlich jeder "Datenstring" in eine Datei mit einem Zeilenteiler zwischen den einzelnen Strins ausgegeben ...
btw: Sie sagen "Zeichen", und ich nehme an, Sie meinen "Byte" ...
aber das Wort "Zeichen" ist in diesen Tagen von UNICODE, in denen nur der 7-Bit-ASCII-Zeichensatz ein einzelnes Byte pro Zeichen verwendet, mehrdeutig geworden ... Und auch innerhalb des Unicode - System Bytezählwerte auf dem Verfahren variieren in Abhängigkeit der Codierung Zeichen , z. B. UTF-8, UTF-16 usw.
Hier ist ein einfaches Skript, um den Unterschied zwischen einem Text- "Zeichen" und Bytes hervorzuheben.
STRING="௵"
echo "CHAR count is: ${#STRING}"
echo "BYTE count is: $(echo -n $STRING|wc -c)"
# CHAR count is: 1
# BYTE count is: 3 # UTF-8 ecnoded (on my system)
Wenn Ihre Länge Zeichen 1 Byte lang und weist auf eine Byte-Länge , dann sollte dieses Skript den Trick tun, auch wenn die Daten Unicode - Zeichen enthält ... dd
sieht nur Bytes unabhängig von einer Lokalisierungs - Einstellungen ...
Dieses Skript dd
liest die Binärdatei und gibt die durch einen "====" - Teiler getrennten Zeichenfolgen aus. Testdaten finden Sie im nächsten Skript
#
div="================================="; echo $div
((skip=0)) # read bytes at this offset
while ( true ) ; do
# Get the "length" byte
((count=1)) # count of bytes to read
dd if=binfile bs=1 skip=$skip count=$count of=datalen 2>/dev/null
(( $(<datalen wc -c) != count )) && { echo "INFO: End-Of-File" ; break ; }
strlen=$((0x$(<datalen xxd -ps))) # xxd is shipped as part of the 'vim-common' package
#
# Get the string
((count=strlen)) # count of bytes to read
((skip+=1)) # read bytes from and including this offset
dd if=binfile bs=1 skip=$skip count=$count of=dataline 2>/dev/null
ddgetct=$(<dataline wc -c)
(( ddgetct != count )) && { echo "ERROR: Line data length ($ddgetct) is not as expected ($count) at offset ($skip)." ; break ; }
echo -e "\n$div" >>dataline # add a newline for TEST PURPOSES ONLY...
cat dataline
#
((skip=skip+count)) # read bytes from and including this offset
done
#
echo
Ausfahrt
Dieses Skript erstellt Testdaten, die ein 3-Byte-Präfix pro Zeile enthalten ...
Das Präfix ist ein einzelnes UTF-8-codiertes Unicode-Zeichen ...
# build test data
# ===============
prefix="௵" # prefix all non-zero length strings will this obvious 3-byte marker.
prelen=$(echo -n $prefix|wc -c)
printf \\0 > binfile # force 1st string to be zero-length (to check zero-length logic)
( lmax=3 # line max ... the last on is set to 255-length (to check max-length logic)
for ((i=1;i<=$lmax;i++)) ; do # add prefixed random length lines
suflen=$(numrandom /0..$((255-prelen))/) # random length string (min of 3 bytes)
((i==lmax)) && ((suflen=255-prelen)) # make last line full length (255)
strlen=$((prelen+suflen))
printf \\$((($strlen/64)*100+$strlen%64/8*10+$strlen%8))"$prefix"
for ((j=0;j<suflen;j++)) ; do
byteval=$(numrandom /9,10,32..126/) # output only printabls ASCII characters
printf \\$((($byteval/64)*100+$byteval%64/8*10+$byteval%8))
done
# 'numrandom' is from package 'num-utils"
done
) >>binfile
#