¿Cómo divido una cadena en un delimitador en Bash?

Resuelto stefanB asked hace 15 años • 38 respuestas

Tengo esta cadena almacenada en una variable:

IN="[email protected];[email protected]"

Ahora me gustaría dividir las cadenas por ;delimitador para tener:

ADDR1="[email protected]"
ADDR2="[email protected]"

No necesito necesariamente las variables ADDR1y ADDR2. Si son elementos de una matriz, aún mejor.


Después de las sugerencias de las respuestas a continuación, terminé con lo siguiente, que es lo que buscaba:

#!/usr/bin/env bash

IN="[email protected];[email protected]"

mails=$(echo $IN | tr ";" "\n")

for addr in $mails
do
    echo "> [$addr]"
done

Producción:

> [[email protected]]
> [[email protected]]

Hubo una solución que implicaba configurar Internal_field_separator (IFS) en ;. No estoy seguro de qué pasó con esa respuesta, ¿cómo se restablece IFSel valor predeterminado?

RE: IFSsolución, probé esto y funciona, mantengo la antigua IFSy luego la restauro:

IN="[email protected];[email protected]"

OIFS=$IFS
IFS=';'
mails2=$IN
for x in $mails2
do
    echo "> [$x]"
done

IFS=$OIFS

Por cierto, cuando lo intenté

mails2=($IN)

Solo obtuve la primera cadena cuando la imprimí en bucle, sin corchetes $INfunciona.

stefanB avatar May 28 '09 09:05 stefanB
Aceptado

Puede configurar la variable del separador de campos interno (IFS) y luego dejar que se analice en una matriz. Cuando esto sucede en un comando, la asignación a IFSsolo se realiza en el entorno de ese comando (a read). Luego analiza la entrada de acuerdo con el IFSvalor de la variable en una matriz, que luego podemos iterar.

Este ejemplo analizará una línea de elementos separados por ;y los insertará en una matriz:

IFS=';' read -ra ADDR <<< "$IN"
for i in "${ADDR[@]}"; do
  # process "$i"
done

Este otro ejemplo es para procesar todo el contenido de $IN, cada vez una línea de entrada separada por ;:

while IFS=';' read -ra ADDR; do
  for i in "${ADDR[@]}"; do
    # process "$i"
  done
done <<< "$IN"
Johannes Schaub - litb avatar May 28 '2009 02:05 Johannes Schaub - litb

Tomado de la matriz dividida del script de shell Bash :

IN="[email protected];[email protected]"
arrIN=(${IN//;/ })
echo ${arrIN[1]}                  # Output: [email protected]

Explicación:

Esta construcción reemplaza todas las apariciones de ';'(la inicial //significa reemplazo global) en la cadena INcon ' '(un solo espacio), luego interpreta la cadena delimitada por espacios como una matriz (eso es lo que hacen los paréntesis circundantes).

La sintaxis utilizada dentro de las llaves para reemplazar cada ';'carácter con un ' 'carácter se llama Expansión de parámetros .

Hay algunos errores comunes:

  1. Si la cadena original tiene espacios, necesitarás usar IFS :
  • IFS=':'; arrIN=($IN); unset IFS;
  1. Si la cadena original tiene espacios y el delimitador es una nueva línea, puede configurar IFS con:
  • IFS=$'\n'; arrIN=($IN); unset IFS;
palindrom avatar Mar 10 '2011 09:03 palindrom