¿Cómo evito que `read` con` IFS` combine caracteres de espacio en blanco? [duplicar]
Tome este fragmento de código que lee datos separados por |
DATA1="Andreas|Sweden|27"
DATA2="JohnDoe||30" # <---- UNKNOWN COUNTRY
while IFS="|" read -r NAME COUNTRY AGE; do
echo "NAME: $NAME"; echo "COUNTRY: $COUNTRY";
echo "AGE: $AGE"; done<<<"$DATA2"
SALIDA:
NOMBRE: JohnDoe
PAÍS:
EDAD: 30
Debería funcionar de manera idéntica a este fragmento de código, donde estamos haciendo exactamente lo mismo, solo usándolo \t
como separador en lugar de|
DATA1="Andreas Sweden 27"
DATA2="JohnDoe 30" # <---- THERE ARE TWO TABS HERE
while IFS=$'\t' read -r NAME COUNTRY AGE; do echo "NAME: $NAME";
echo "COUNTRY: $COUNTRY"; echo "AGE: $AGE";
done<<<"$DATA2"
Pero no es así.
OUTPUT:
NAME: JohnDoe
COUNTRY: 30
AGE:
Bash, or read
or IFS
or some other part of the code is globbing together the whitespace when it isn't supposed to. Why is this happening, and how can I fix it?
Respuestas
bash
is behaving exactly as it should. From the bash
documentation:
The shell treats each character of IFS as a delimiter, and splits the results of the other expansions into words on these characters. If IFS is unset, or its value is exactly
<space><tab><newline>
, the default, then sequences of<space>
,<tab>
, and<newline>
at the beginning and end of the results of the previous expansions are ignored, and any sequence of IFS characters not at the beginning or end serves to delimit words. If IFS has a value other than the default, then sequences of the whitespace characters space and tab are ignored at the beginning and end of the word, as long as the whitespace character is in the value of IFS (an IFS whitespace character). Any character in IFS that is not IFS whitespace, along with any adjacent IFS whitespace characters, delimits a field. A sequence of IFS whitespace characters is also treated as a delimiter.
To overcome this "feature", you could do something like the following:
#!/bin/bash
DATA1="Andreas Sweden 27"
DATA2="JohnDoe 30" # <---- THERE ARE TWO TABS HERE
echo "$DATA2" | sed 's/\t/;/g' | while IFS=';' read -r NAME COUNTRY AGE; do echo "NAME: $NAME"
echo "COUNTRY: $COUNTRY" echo "AGE: $AGE"
done