|
From: | Julio C. Neves |
Subject: | Re: [shell-script-pt] Idiossincrasia do read |
Date: | Wed, 24 Feb 2021 12:15:19 -0500 |
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
_______________________________________________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.
[Prev in Thread] | Current Thread | [Next in Thread] |