cambiando IFS temporalmente antes de un bucle for [duplicado]

Aug 16 2020

Sé que SHELLpermite que la asignación de variables se realice inmediatamente antes de un comando, de modo que IFS=":" read a b c d <<< "$here_string"funcione ...

Lo que me preguntaba es si tales asignaciones no funcionan cuando se hacen con declaraciones compuestas como bucles. Intenté algo como, IFS=":" for i in $PATH; do echo $i; donepero resulta en un error de sintaxis. Siempre podía hacer algo así oldIFS="$IFS"; IFS=":"; for....; IFS="$oldIFS", pero quería saber si había alguna forma de hacer que esas asignaciones en línea funcionen para declaraciones compuestas como forbucles.

Respuestas

3 Quasímodo Aug 16 2020 at 21:12

fores una palabra reservada y, como tal, sigue reglas especiales :

Las siguientes palabras se reconocerán como palabras reservadas:

! {} case do done elif else esac fi for if in then hasta while

Este reconocimiento solo ocurrirá cuando no se cite ninguno de los caracteres y cuando la palabra se use como:

  • La primera palabra de un comando

  • La primera palabra que sigue a una de las palabras reservadas que no sea case , for o in

  • La tercera palabra en un comando de caso (solo en es válido en este caso)

  • La tercera palabra en un comando for (solo en y do son válidos en este caso)

Si intentas

IFS=":" for i in $PATH; do echo $i; done

, según las reglas anteriores, eso no es un forbucle, ya que la palabra clave no es la primera palabra del comando. Pero tu intención se puede lograr con

IFS=: printf '%s\n' $PATH

$PATHsufre la división de palabras :como se esperaba y cada palabra resultante se imprime printf, seguida de una nueva línea.


Puede estar familiarizado con este enfoque válido:

while IFS= read -r line; do

whilees la primera palabra del comando y la IFSasignación se aplica a read, por lo que todo está bien.