ACTUALIZACIÓN (en retrospectiva): ... Esta pregunta / respuesta (mi respuesta) me hace pensar en el perro que sigue persiguiendo el auto ... Un día, finalmente, se pone al día con el auto ... De acuerdo, lo atrapó, pero realmente no puede hacer mucho con eso ... Este anser 'atrapa' las cadenas, pero luego no puedes hacer mucho con ellas, si tienen bytes nulos incrustados ... (entonces un gran +1 a la respuesta de Gilles .. otro idioma puede estar en orden aquí.)
dd
lee todos y cada uno de los datos ... Ciertamente no se reducirá a cero como una "longitud" ... pero si tiene \ x00 en cualquier parte de sus datos, deberá ser creativo sobre cómo manejarlo; dd
no tiene problemas con él, pero su script de shell tendrá problemas (pero depende de lo que quiera hacer con los datos) ... Lo siguiente básicamente genera cada "cadena de datos", en un archivo con un divisor de línea entre cada cadena ...
por cierto: dices "carácter", y supongo que quieres decir "byte" ...
pero la palabra "carácter" se ha vuelto ambigua en estos días de UNICODE, donde solo el conjunto de caracteres ASCII de 7 bits usa un solo byte por carácter ... E incluso dentro del sistema Unicode, los recuentos de bytes varían según el método de codificación de caracteres , por ejemplo. UTF-8, UTF-16, etc.
Aquí hay un script simple para resaltar la diferencia entre un "carácter" de texto y bytes.
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)
Si su carácter de longitud es de 1 byte e indica una longitud de byte , entonces este script debería hacer el truco, incluso si los datos contienen caracteres Unicode ... dd
solo ve bytes independientemente de la configuración regional ...
Este script se utiliza dd
para leer el archivo binario y genera las cadenas separadas por un divisor "====" ... Consulte el siguiente script para ver los datos de prueba
#
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
salida
Este script crea datos de prueba que incluyen un prefijo de 3 bytes por línea ...
El prefijo es un único carácter Unicode codificado en 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
#