bash leitura de uma nova linha, printf reporta caractere 0

3

Eu uso a função bash printf para imprimir códigos ASCII de caracteres em um arquivo de entrada, mas por algum motivo printf gera o código ascii 0 para LF caracteres, em vez de 10. Alguma idéia por quê?

while IFS= read -r -n1 c
do
ch=$(LC_CTYPE=C printf "%d\n" "'$c") # convert to integer
echo "ch=$ch"
done < input_file_name

Para ser honesto, eu nem tenho certeza se isso é um problema com printf ou é a função read , que fornece o valor errado de LF ... Existem outras maneiras de converter caracteres em ASCII? usando comandos bash?

    
por John Smith 20.04.2016 / 09:12

2 respostas

2

primeiro sua função printf funciona perfeitamente

$ export c=" "
$ LC_CTYPE=C printf "%d\n" "'$c"
32

Mas executar a linha de script com -vx mostra que os dados que chegam a essa linha estão errados (não vou colar essa saída)

Então eu acho que é a leitura que está errada. O delimitador EOL padrão para leitura é newline, então tentei alterar isso. Isso parece funcionar

while IFS= read -d
$ export c=" "
$ LC_CTYPE=C printf "%d\n" "'$c"
32
-r -n1 c; do ch=$(LC_CTYPE=C printf "%d\n" "'$c") ; echo "ch=$ch"; done < input_file_name
    
por 20.04.2016 / 12:39
2

O read não está errado, mas você está interpretando os resultados de forma um pouco errada.

O marcador EOL é \n , portanto, inserir esse caractere significa que read encontrou uma "linha" sem caracteres. Observe que a variável $c não contém o \n :

while IFS= read -r c
do
    test -z "$c" && echo "Zero length string" || echo "I read '$c'"
done

Ao adicionar -n1 você está limitando o número de caracteres que podem ser lidos apenas para um. Assim como no exemplo acima, o \n não faz parte da string aceita, então read retorna "nada" quando você digita \n :

while IFS= read -r -n1 c
do
    test -z "$c" && echo "Zero length string" || echo "I read '$c'"
done

O comando printf é interessante. Se você alimenta uma string de comprimento zero prefixada com aspas simples, também obtém "0", então suspeito que a resposta aqui seja "não faça isso":

LC_CTYPE=C printf "%d" "'" | od -c
0000000   0
    
por 20.04.2016 / 13:01