UPDATE (em retrospecto): ... Esta pergunta / resposta (minha resposta) me faz pensar no cachorro que fica perseguindo o carro .. Um dia, finalmente, ele alcança o carro .. Ok, ele pegou isso, mas ele realmente não pode fazer muito com isso ... Este anser 'pega' as cordas, mas então você não pode fazer muito com elas, se elas tiverem embutido bytes nulos ... (então um grande +1 para Gilles responder .. outra língua pode estar em ordem aqui.)
dd
lê todo e qualquer dado ... Certamente não vai atrapalhar zero como "comprimento" ... mas se você tiver \ x00 em qualquer lugar em seus dados, precisa ser criativo como você lida com isso; dd
não tem nenhum problema com isso, mas seu script de shell terá problemas (mas depende do que você deseja fazer com os dados) ... O seguinte basicamente gera cada "cadeia de dados", em um arquivo com um divisor de linha entre cada strin ...
btw: Você diz "personagem", e eu assumo que você quer dizer "byte" ...
mas a palavra "caractere" tornou-se ambígua nesses dias de UNICODE, onde apenas o conjunto de caracteres ASCII de 7 bits usa um único byte por caractere ... E mesmo dentro do sistema Unicode, a contagem de bytes varia dependendo do método de codificação 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 tamanho do caractere for 1 byte e indicar byte-length , esse script deverá funcionar, mesmo que os dados contenham caracteres Unicode. . dd
só vê bytes independentemente de qualquer definição de localidade ...
Este script usa dd
para ler o arquivo binário e gera as sequências separadas por um divisor "====" ... Veja o próximo script para 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
sair
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
#