shell-script-pt
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [shell-script-pt] Idiossincrasia do read


From: Arkanon
Subject: Re: [shell-script-pt] Idiossincrasia do read
Date: Wed, 24 Feb 2021 15:05:59 -0300

De fato, Julio, a modificação do valor de IFS parece ser a solução mais usada/indicada. Certamente a mais clara/compreensível.

MAS, sem alterar o IFS e em relação à múltiplos espaços ou espaços iniciais/finais, o comportamento que me chamou especialmente a atenção é que APENAS quando não indicamos nome ALGUM de variável ao read, espaços são mantidos, como se estivesse sendo assumindo valor vazio para IFS:

$ read <<< "  um  dois  "; echo "R=[$REPLY]"
R=[  um  dois  ]


Esse comportamento "estranho" não se repete nem quando um nome igual ao nome default é indicado:

$ read REPLY <<< "  um  dois  "; echo "R=[$REPLY]"
R=[um  dois]

Especificamente isso, eu achei uma característica inusitada, aparentemente não documentada (pelo menos no man e no help) e quem sabe até incoerente, do read.

Você ou algum outro colega conhece alguma referência original do bash a esse comportamento (quando nenhum nome de variável é indicado)?

Att,

Em qua., 24 de fev. de 2021 às 14:16, Julio C. Neves <julio.neves@gmail.com> escreveu:
Arkanon, acho que meu livro responde à sua dúvida. Olha a seção que tem lá:
---------------------------------------------------------

Esquisitices do IFS no read

Se você estiver usando o IFS padrão, seus caracteres (espaço, <TAB> e <ENTER>) podem ocorrer repetidas vezes entre os campos e serão ignorados. Caso o IFS tenha sido modificado, essa regra não vale. Veja:

$ read Cpo1 Cpo2 Cpo3 <<< "Palavra1     Palavra2"

$ echo "Cpo1=$Cpo1 -- Cpo2=$Cpo2 -- Cpo3=$Cpo3"

Cpo1=Palavra1 -- Cpo2=Palavra2 -- Cpo3=

Neste exemplo, existiam diversos espaços em branco entre as palavras e pode-se notar que eles foram ignorados porque $Cpo2 recebeu Palavra2. Vejamos agora o que acontecerá com um IFS diferente do padrão e com mais de uma ocorrência dele entre as palavras:

$ IFS=: read Cpo1 Cpo2 Cpo3 <<< "Palavra1::Palavra2"

$ echo "Cpo1=$Cpo1 -- Cpo2=$Cpo2 -- Cpo3=$Cpo3"

Cpo1=Palavra1 -- Cpo2= -- Cpo3=Palavra2

Agora $IFS foi alterado para dois-pontos (:) e $Cpo2 ficou vazia porque recebeu o conteúdo nulo (que estaria entre esses dois dois-pontos [::]) e $Cpo3 recebeu a segunda palavra.

Outra esquisitice ocorre quando a variável $IFS é padrão (default) e um de seus componentes (espaço, <TAB> e <ENTER>) ocorre em qualquer quantidade no início ou no fim do texto a ser lido, pois serão totalmente ignorados. Veja um exemplo com o texto a ser lido começando e terminando com quatro espaços em branco:

$ read Cpo1 <<< " Palavra "

$ echo "Cpo1=-$Cpo1-"

Cpo1=-Palavra-

Conforme você pode notar, os brancos que precedem e sucedem Palavra foram ignorados. Os hifens (-) foram colocados para mostrar o início e o fim do texto.

Para que isso não ocorra, devemos colocar um valor nulo na variável $IFS. Veja:

$ IFS= read Cpo1 <<< " Palavra "

$ echo "Cpo1=-$Cpo1-"

Cpo1=- Palavra -

Só para efeito de demonstração, repare que, se $IFS estivesse fora do padrão, essa exceção não ocorreria:

$ IFS=: read Cpo1 Cpo2 Cpo3 <<< "::Palavra"

$ echo "Cpo1=$Cpo1 -- Cpo2=$Cpo2 -- Cpo3=$Cpo3"

Cpo1= -- Cpo2= -- Cpo3=Palavra

--------------------------------------------------
ATENÇÂO Shelleiros! No início de março estarmos começando uma nova turma do curso de Programação em Shell veja detalhes em: https://www.dicas-l.com.br/educacao/index/programacao-shell-linux/

Abraços,
Julio
» Não tem tempo para fazer um curso presencial?
» Na sua cidade não tem nenhum bom curso de Linux?

Também damos treinamento em sua empresa
em qualquer cidadecom certificado e nota fiscal.








Em qua., 24 de fev. de 2021 às 11:13, Arkanon <arkanon@lsd.org.br> escreveu:
PessoAll.

Gostaria de comentar um comportamento do build-in read com o qual me deparei hoje pela primeira vez (que eu lembre):

$ echo -n '  a  ' | while read -n1; do echo "[$REPLY]"; done
[ ]
[ ]
[a]
[ ]
[ ]
$ echo -n '  a  ' | while read -n1 REPLY; do echo "[$REPLY]"; done
[]
[]
[a]
[]
[]
$ echo -n '  a  ' | while read -n1 RESP; do echo "[$RESP]"; done
[]
[]
[a]
[]
[]


e

$ echo '  a  b  ' | while read; do echo "[$REPLY]"; done
[  a  b  ]
$ echo '  a  b  ' | while read REPLY; do echo "[$REPLY]"; done
[a  b]
$ echo '  a  b  ' | while read RESP; do echo "[$RESP]"; done
[a  b]


MAS

$ echo '  a  b  ' | while IFS=$'\t\n' read RESP; do echo "[$RESP]"; done
[  a  b  ]


Ou seja: quando não se indica um nome de variável no read (e portanto o resultado fica armazenado na variável default REPLY), espaços presentes "nas pontas" da string lida não são mantidos. Mesmo indicando uma variável com um nome igual ao default.

Contudo; SE não for indicado um nome de variável para o resultado do read OU for removido o caracter "espaço" do conjunto de caracteres separadores de campo interno (IFS); ENTÃO eventuais espaços "nas pontas" são mantidos.

Não identifiquei nenhuma referência a esse comportamento no man do bash ou no help do read (help read). Será que é um comportamento tão óbvio assim?
Uma rápida pesquisa no Google mostra que mais gente já se deparou com esse problema, assumindo a mesma explicação.

Att,

--
(o_  @arkanon  (Twitter)     __o
//\   arkanon@lsd.org.br   _`\<,
V_/_      www.lsd.org.br  (_)/(_)
---------------------------------
_______________________________________________
Lista brasileira de usuários de shell script
Endereço de e-mail da lista: shell-script-pt@nongnu.org
Para se inscrever ou desinscrever acesse: https://lists.nongnu.org/mailman/listinfo/shell-script-pt
Para ver os arquivos da lista (mensagens anteriores) e pesquisar nelas, acesse https://lists.nongnu.org/archive/html/shell-script-pt/

NOTA: A lista anterior, no Yahoo Groups, foi *desativada*. Por favor utilize somente esta.
_______________________________________________
Lista brasileira de usuários de shell script
Endereço de e-mail da lista: shell-script-pt@nongnu.org
Para se inscrever ou desinscrever acesse: https://lists.nongnu.org/mailman/listinfo/shell-script-pt
Para ver os arquivos da lista (mensagens anteriores) e pesquisar nelas, acesse https://lists.nongnu.org/archive/html/shell-script-pt/

NOTA: A lista anterior, no Yahoo Groups, foi *desativada*. Por favor utilize somente esta.


--
(o_  @arkanon  (Twitter)     __o
//\   arkanon@lsd.org.br   _`\<,
V_/_      www.lsd.org.br  (_)/(_)
---------------------------------

reply via email to

[Prev in Thread] Current Thread [Next in Thread]