AGGIORNAMENTO (con il senno di poi): ... Questa domanda / risposta (la mia risposta) mi fa pensare al cane che continua a inseguire la macchina .. Un giorno, finalmente, raggiunge l'auto .. Va bene, l'ha presa, ma non può davvero farci molto ... Questa risposta "cattura" le stringhe, ma poi non puoi farci molto, se hanno dei byte nulli incorporati ... (quindi un grande +1 a Gilles risponde .. un'altra lingua potrebbe essere in ordine qui.)
dd
legge tutti i dati ... Certamente non si sfoglia a zero come "lunghezza" ... ma se hai \ x00 in qualsiasi punto dei tuoi dati, dovrai essere creativo nel modo in cui li gestisci; dd
non ha alcun problema con esso, ma lo script della shell avrà problemi (ma dipende da cosa vuoi fare con i dati) ... Di seguito, in sostanza, ogni "stringa di dati" viene emessa, in un file con un divisore di linea tra ogni strin ...
btw: dici "carattere", e suppongo che intendi "byte" ...
ma la parola "carattere" è diventata ambigua in questi giorni di UNICODE, dove solo il set di caratteri ASCII a 7 bit utilizza un singolo byte per carattere ... E anche all'interno del sistema Unicode, il conteggio dei byte varia in base al metodo di codifica dei caratteri , ad es. UTF-8, UTF-16, ecc.
Ecco un semplice script per evidenziare la differenza tra un "carattere" di testo e byte.
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)
Se il tuo carattere di lunghezza è lungo 1 byte e indica una lunghezza di byte , questo script dovrebbe fare il trucco, anche se i dati contengono caratteri Unicode ... dd
vede solo byte indipendentemente da qualsiasi impostazione locale ...
Questo script utilizza dd
per leggere il file binario e genera le stringhe separate da un divisore "====" ... Vedi lo script successivo per i dati di test
#
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
Uscita
Questo script crea dati di test che includono un prefisso di 3 byte per riga ...
Il prefisso è un singolo carattere Unicode codificato UTF-8 ...
# 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
#