¿Cómo divido una cadena en un delimitador en Bash?
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 ADDR1
y 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 IFS
el valor predeterminado?
RE: IFS
solución, probé esto y funciona, mantengo la antigua IFS
y 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 $IN
funciona.
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 IFS
solo se realiza en el entorno de ese comando (a read
). Luego analiza la entrada de acuerdo con el IFS
valor 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"
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 IN
con ' '
(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:
- Si la cadena original tiene espacios, necesitarás usar IFS :
IFS=':'; arrIN=($IN); unset IFS;
- Si la cadena original tiene espacios y el delimitador es una nueva línea, puede configurar IFS con:
IFS=$'\n'; arrIN=($IN); unset IFS;