Estaba leyendo este hilo: ¿Cómo recorrer las líneas de un archivo?
¿Qué es IFS
? ¿Y cuál es su uso en el contexto de for
-loops?
Estaba leyendo este hilo: ¿Cómo recorrer las líneas de un archivo?
¿Qué es IFS
? ¿Y cuál es su uso en el contexto de for
-loops?
Respuestas:
IFS
significa : es un personaje que separa los campos. En el ejemplo que publicó, se establece en un nuevo carácter de línea ( ); así que después de configurarlo, procesará el texto línea por línea. En ese ejemplo, podría cambiar el valor de (a alguna letra que tenga en su archivo de entrada) y verificar cómo se dividirá el texto.Input
Internal Field Separator
\n
for
IFS
Por cierto, de la respuesta que publicó la segunda solución es que se recomienda ...
Como @jasonwryan notó, no es Input
sino Internal
. Nombre de donde Input
proviene awk
también OFS
- Output Field Separator
.
S
fue para el separador en el shell Bourne de donde se originó. En el shell Korn y en la mayoría de los otros shell similares a Bourne, como se ha especificado ahora POSIX
, S
es para Delimitador (solo estira tu imaginación un poco) ya que, A::B:
por ejemplo, se divide en "A", "" y "B" (sin extra ""). Eso es diferente de awk
's FS
o la s
bandera de expansión de parámetros de zsh
.
IFS
no está directamente relacionado con el bucle, está relacionado con la división de palabras. IFS
determina indirectamente cómo la salida del comando se divide en partes sobre las que el ciclo itera.
Cuando tiene una sustitución de variable desprotegida $foo
o una sustitución de comando $(foo)
, hay dos casos:
"$foo"
o en una asignación variable x=$foo
, la cadena resultante de la sustitución se utiliza tal cual.$IFS
se considera un separador de palabras. Por ejemplo, IFS=":"; foo="12:34::78"; echo $foo
impresiones 12 34 78
(con dos espacios entre 34
y 78
, ya que hay una palabra vacía).foo="*"; echo $foo
imprime la lista de archivos en el directorio actual.Para los bucles, como muchos otros contextos, espere una lista de palabras. Entonces
for x in $(foo); do …
se divide $(foo)
en palabras y trata cada palabra como un patrón global. El valor predeterminado de IFS
es space, tab y newline , por lo que si foo
imprime dos líneas hello world
y howdy
luego el cuerpo del bucle se ejecuta con x=hello
, entonces x=world
y x=howdy
. Si IFS
se cambia explícitamente para contener solo una nueva línea, el bucle se ejecuta para hello world
y howdy
. Si IFS
se cambia a ser o
, entonces el bucle se ejecuta para hell
, w
, rldh
(donde 
es un carácter de nueva línea) y wdy
.
"IFS indirectly determines how ..."
?
IFS
(directamente) determina cómo se divide la salida de la sustitución del comando, que luego (indirectamente) determina sobre qué se repite el bucle.
Desde man bash
IFS El separador de campo interno que se usa para dividir palabras después de la expansión y para dividir líneas en palabras con el comando de lectura incorporado. El valor predeterminado es "<space> <tab> <newline>".
Esta es una de las variables internas de Bash. Determina cómo Bash reconoce campos, o límites de palabras, cuando interpreta cadenas de caracteres.
Si bien el valor predeterminado es el espacio en blanco (espacio, tabulación y nueva línea), se puede cambiar, por ejemplo, para analizar un archivo de datos separados por comas.
Además de las excelentes respuestas anteriores, permítanme agregar que IFS es muy útil para un análisis eficiente y portátil en casos simples en combinación con el conjunto . Eficiente, porque evita el uso de subcapas y herramientas de desove como grep o sed:
resolutions="640x480,320x240"
xIFS=$IFS
IFS=','
for res in $resolutions; do
xxIFS=$IFS
IFS='x'
set -- $res
width=$1
height=$2
# handle width and height
IFS=$xxIFS
done;
IFS=$xIFS
Solo tenga en cuenta que necesitamos almacenar y recuperar el valor anterior de IFS para evitar roturas no deseadas en otras partes del script.