Intentando dividir una cadena en dos variables

Estoy tratando de dividir una cadena en dos variables (sin tener que usar un ciclo while):

var="hello:world" IFS=':' read var1 var2 <<< $var echo "var1: $var1" echo "var2: $var2" 

pero no estoy obteniendo el resultado deseado:

 var1: 'hello world' var2: '' 

¿Podría alguien explicar por favor si es posible hacerlo de esta manera (o de manera similar)?

Este es un error en Bash 4.2. Vea la respuesta de chepner para una explicación adecuada.


Se trata de citas. Utilizar:

 IFS=':' read var1 var2 <<< "$var" ^ ^ 

en lugar de

 IFS=':' read var1 var2 <<< $var 

Ver resultado:

 $ IFS=':' read var1 var2 <<< "$var" $ echo "var1=$var1, var2=$var2" var1=hello, var2=world 

Pero

 $ IFS=':' read var1 var2 <<< $var $ echo "var1=$var1, var2=$var2" var1=hello world, var2= 

FYI para lectores futuros:

Después de discutir esto con los desarrolladores, parece que este es un error en bash 4.2, y se ha corregido en la próxima versión 4.3. Desde el registro de cambio de twig de desarrollo

rrrr. Se corrigieron varios problemas con IFS cuando aparece en el entorno temporal y se usa en las redirecciones.

Aunque siempre es una buena idea citar expansiones de parámetros de todos modos, el código del OP debería funcionar como se pretendía sin comillas.


Aquí hay una explicación del error. Con el código

 var="hello:world" IFS=':' read var1 var2 <<< $var 

el $var comillas debe ser una sola palabra, ya que no contiene ningún carácter en el valor global de IFS (es decir, no hay espacio en blanco). read debería ver la cadena hello:world . Debido a que recibió dos argumentos, debe aplicar la división de palabras usando su valor local de IFS , produciendo hello y world que están asignados a var1 y var2 , respectivamente.

El error es que la cadena aquí parece sufrir división parcial usando el valor "filtrado" de IFS se pasa para read . Como resultado, la cadena se convierte en hello world , pero todavía se ve por read como una sola palabra. Como esa palabra no contiene un : read no se divide en dos palabras, y toda la cadena se asigna a var1 .

En la bash 4.3, como se documentó, la expansión de $var no se divide por división de palabras como argumento para el operador <<< ; el código

 var="hello:1:2 world" IFS=: read var1 var2 <<< $var 

establece var1 a hello y var2 a 1:2 world .