UPDATE (com retrospectiva): ... Esta pergunta / resposta (minha resposta) me faz pensar no cachorro que continua perseguindo o carro .. Um dia, finalmente, ele alcança o carro .. Ok, ele pegou, mas ele realmente não pode fazer muito com isso ... Esse anser 'pega' as strings, mas você não pode fazer muito com elas, se elas tiverem bytes nulos incorporados ... (portanto, um grande +1 para Gilles responde .. outro idioma pode estar em ordem aqui.)
dd
lê todos e quaisquer dados ... Certamente, não será exibido em zero como um "comprimento" ... mas se você tiver \ x00 em qualquer lugar dos seus dados, precisará ser criativo ao lidar com eles;dd
não possui propblems, mas seu script shell terá problemas (mas depende do que você deseja fazer com os dados) ... O seguinte basicamente gera cada "string de dados" em um arquivo com um divisor de linha entre cada strin ...
btw: Você diz "caractere" e suponho que você queira dizer "byte" ...
mas a palavra "caractere" tornou-se ambígua nos dias de UNICODE, onde apenas o conjunto de caracteres ASCII de 7 bits usa um único byte por caractere ... E mesmo no sistema Unicode, a contagem de bytes varia de acordo com o método de codificação de caracteres , por exemplo. UTF-8, UTF-16, etc.
Aqui está um script simples para destacar a diferença entre um "caractere" de texto e 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)
Se o seu caractere de comprimento tiver 1 byte de comprimento e indicar um comprimento de byte , esse script deverá executar o truque, mesmo que os dados contenham caracteres Unicode ... dd
só vê bytes independentemente de qualquer configuração de localidade ...
Este script usa dd
para ler o arquivo binário e gera as strings separadas por um divisor "====" ... Consulte o próximo script para obter dados de teste
#
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
Saída
Este script cria dados de teste que incluem um prefixo de 3 bytes por linha ...
O prefixo é um único caractere Unicode codificado em 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
#