Buscar..


Sintaxis

  • Establezca IFS en nueva línea: IFS = $ '\ n'
  • Establecer IFS en cadena nula: IFS =
  • Establezca IFS en / carácter: IFS = /

Parámetros

Parámetro Detalles
IFS Separador de campo interno
-X Imprimir comandos y sus argumentos a medida que se ejecutan (opción de Shell)

Observaciones

  • La división de palabras no se realiza durante las tareas, por ejemplo, newvar=$var
  • La división de palabras no se realiza en la construcción [[ ... ]]
  • Use comillas dobles en las variables para evitar la división de palabras

Partiendo con IFS

Para ser más claros, vamos a crear un script llamado showarg :

#!/usr/bin/env bash
printf "%d args:" $#
printf " <%s>" "$@"
echo

Ahora veamos las diferencias:

$ var="This is an example"
$ showarg $var
4 args: <This> <is> <an> <example>

$var se divide en 4 args. IFS son caracteres de espacios en blanco y, por lo tanto, la división de palabras ocurrió en espacios

$ var="This/is/an/example"
$ showarg $var
1 args: <This/is/an/example>

En la división de palabras anterior no se produjo porque no se encontraron los caracteres IFS .

Ahora vamos a establecer IFS=/

$ IFS=/
$ var="This/is/an/example"
$ showarg $var
4 args: <This> <is> <an> <example>

El $var se divide en 4 argumentos, no un solo argumento.

¿Qué, cuándo y por qué?

Cuando el shell realiza la expansión de parámetros , la sustitución de comandos , la expansión variable o aritmética , busca límites de palabras en el resultado. Si se encuentra un límite de palabra, el resultado se divide en varias palabras en esa posición. El límite de la palabra se define mediante una variable de shell IFS (Separador de campo interno). El valor predeterminado para IFS es espacio, tabulador y nueva línea, es decir, la división de palabras se producirá en estos tres caracteres de espacio en blanco si no se evita explícitamente.

set -x
var='I am
a
multiline string'
fun() {
    echo "-$1-"
    echo "*$2*"
    echo ".$3."
}
fun $var

En el ejemplo anterior, así es como se ejecuta la función fun :

fun I am a multiline string

$var se divide en 5 argumentos, solo I , am y a se imprimirán.

IFS y división de palabras

Vea qué, cuándo y por qué, si no sabe acerca de la afiliación de IFS a la división de palabras

vamos a configurar el IFS en caracteres de espacio solamente:

set -x
var='I am
a
multiline string'
IFS=' '
fun() {
    echo "-$1-"
    echo "*$2*"
    echo ".$3."
}
fun $var

Esta vez la división de palabras solo funcionará en espacios. La función de fun se ejecutará así:

fun I 'am
a
multiline' string

$var se divide en 3 args. I , am\na\nmultiline y string se imprimirán

Vamos a configurar el IFS a nueva línea solamente:

IFS=$'\n'
...

Ahora la fun será ejecutada como:

fun 'I am' a 'multiline string'

$var se divide en 3 args. I am , se imprimirá a multiline string

Veamos qué sucede si establecemos IFS en cadena nula:

IFS=
...

Esta vez la fun se ejecutará así:

fun 'I am
a
multiline string'

$var no se divide, es decir, se mantuvo como un solo argumento.

Puede evitar la división de palabras configurando el IFS en cadena nula

Una forma general de evitar la división de palabras es usar comillas dobles:

fun "$var"

evitará la división de palabras en todos los casos discutidos anteriormente, es decir, la función fun se ejecutará con un solo argumento.

Malos efectos de la división de palabras.

$ a='I am a string with spaces'
$ [ $a = $a ] || echo "didn't match"
bash: [: too many arguments
didn't match

[ $a = $a ] se interpretó como [ I am a string with spaces = I am a string with spaces ] . [ es el comando de test para el que I am a string with spaces no es un solo argumento, ¡¡es más bien 6 argumentos !!

$ [ $a = something ] || echo "didn't match"
bash: [: too many arguments
didn't match

[ $a = something ] se interpretó como [ I am a string with spaces = something ]

$ [ $(grep . file) = 'something' ]
bash: [: too many arguments

El comando grep devuelve una cadena multilínea con espacios, así que puedes imaginar cuántos argumentos hay ...: D

Vea qué, cuándo y por qué para lo básico.

Utilidad de la división de palabras

Hay algunos casos donde la división de palabras puede ser útil:

Rellenando matriz:

arr=($(grep -o '[0-9]\+' file))

Esto llenará arr con todos los valores numéricos encontrados en el archivo

Corriendo a través del espacio palabras separadas:

words='foo bar baz'
for w in $words;do
    echo "W: $w"
done

Salida:

W: foo
W: bar
W: baz

Pasando parámetros separados por espacios que no contienen espacios en blanco:

packs='apache2 php php-mbstring php-mysql'
sudo apt-get install $packs

o

packs='
apache2
php
php-mbstring
php-mysql
'
sudo apt-get install $packs

Esto instalará los paquetes. Si cita dos veces los $packs se producirá un error.

Unquoetd $packs está enviando todos los nombres de paquetes separados por espacios como argumentos a apt-get , mientras que si lo cita enviará la cadena de $packs como un solo argumento y luego apt-get intentará instalar un paquete llamado apache2 php php-mbstring php-mysql (para el primero) que obviamente no existe

Vea qué, cuándo y por qué para lo básico.

División por cambios de separador.

Simplemente podemos reemplazar los separadores del espacio a una nueva línea, como se muestra en el siguiente ejemplo.

echo $sentence | tr " " "\n"

Dividirá el valor de la sentence variable y lo mostrará línea por línea respectivamente.



Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow