Tengo la cadena a continuación:
/a585/app/data/CCN_text/CCN_split_files/ccn.email.list.file07 | /svr00c8/n585 | /a585/app/data/CCN_text | /a585/app/data/CCN_text | /a585/app/data/muttrc | 153.2.254.229 | /a001/odbi_land/ondemand/download/scriptload | DVLP | cmodappl | ondemand
Soy principiante en Linux. ¿Cómo puedo separar usando "|"? como delimitador y asignar en una variable? Estoy pasando la cadena completa como parámetro y necesito dividir/cortar los campos por separado.
Por ejemplo:
function()
{
while read -r record; do
## here i need the fields to cut the fields and assign to a variable #####
done < $0
}
bash -c function "/a585/app/data/CCN_text/CCN_split_files/ccn.email.list.file07 | /svr00c8/n585 | /a585/app/data/CCN_text | /a585/app/data/CCN_text | /a585/app/data/muttrc | 153.2.254.229 | /a001/odbi_land/ondemand/download/scriptload | DVLP | cmodappl | ondemand"
Cuando probé el ejemplo anterior arroja un error $0: ambiguous redirect
.
Respuesta1
Puedes usar tr
para separar usando delimitador.
En el siguiente ejemplo reemplazamos |
pornewline
variable=$(echo "/a585/app/data/CCN_text/CCN_split_files/ccn.email.list.file07 | /svr00c8/n585 | /a585/app/data/CCN_text | /a585/app/data/CCN_text | /a585/app/data/muttrc | 153.2.254.229 | /a001/odbi_land/ondemand/download/scriptload | DVLP | cmodappl | ondemand" | tr "|" "\n")
echo $variable
También puedes usar
echo yourtext | tr -d "|"
Vercomando tr
Respuesta2
Hay tantas cuestiones además de la principal.
ambiguous redirect
es porquetu código carece de comillas dobles.- La redirección
<
toma datos de un archivo. Su cadena no apunta a un archivo (ruta). En Bash puedes tomar datos de una cadena con<<<
. function
es una palabra reservada. Hay una manera de nombrar una funciónfunction
, pero su uso posterior es inconveniente.- (terminología en su comentario) La función no es un niño.
- Se llama a una función por su nombre, no por
bash -c
.Mi respuesta a tu otra pregunta.aplica. - Entonces al primer argumento se le llama
$1
, no$0
.
Este código funciona, aunque no estoy seguro de que sea exactamente lo que quieres:
#!/bin/bash
split_string ()
{
readarray -t arrayv < <(tr '|' '\n' <<< "$1")
}
split_string '/a585/app/data/CCN_text/CCN_split_files/ccn.email.list.file07 | /svr00c8/n585 | /a585/app/data/CCN_text | /a585/app/data/CCN_text | /a585/app/data/muttrc | 153.2.254.229 | /a001/odbi_land/ondemand/download/scriptload | DVLP | cmodappl | ondemand'
# now arrayv is an array variable (indexed from 0)
# retrieving few values
echo "${arrayv[0]}"
echo "${arrayv[5]}"
echo "${arrayv[9]}"
Notas:
- Usted citó dos veces la cadena. Recuerde que una cadena entre comillas dobles sufre ciertas expansiones. Su cadena no contiene nada que pueda expandirse (por ejemplo
$
), por lo que las comillas dobles están bien en este caso particular. En general, utilice comillas simples para suprimir las expansiones. readarray
es sinónimo demapfile
. Invocarhelp mapfile
para aprender.- Otros forrajes de investigación:
<<<
,<( … )
,matrices. - No hay forma de introducir
export
una variable de matriz en el entorno. Podríamos decir
readarray
que se use|
como delimitador:readarray -t -d '|' arrayv <<< "$1"
pero luego el último "campo" incluiría un carácter de nueva línea al final (aparecería debido a cómo
<<<
funciona). Convierto todos los delimitadores en nuevas líneastr
y luegoreadarray
uso su configuración predeterminada (nuevas líneas como delimitadores).Los espacios no pertenecen a delimitadores, se convierten en parte de los valores almacenados. Úselo
sed
en lugar detr
para convertir subcadenas de delimitadores con espacios adyacentes en caracteres de nueva línea única. Lareadarray …
línea será:readarray -t arrayv < <(sed 's/ *| */\n/g' <<< "$1")
Si va a utilizar la función sólo una vez, no necesita ninguna función. Esta línea (fuera de cualquier función) hará el trabajo:
readarray -t arrayv < <(tr '|' '\n' <<< '/a585/app/data/CCN_text/CCN_split_files/ccn.email.list.file07 | /svr00c8/n585 | /a585/app/data/CCN_text | /a585/app/data/CCN_text | /a585/app/data/muttrc | 153.2.254.229 | /a001/odbi_land/ondemand/download/scriptload | DVLP | cmodappl | ondemand')
Definí una función (y luego la usé solo una vez) porque intentaste definir una.
Si su cadena de entrada consta de un número fijo de campos y los campos tienen significado, puede ser bueno asignarlos a diferentes variables (regulares, no de matriz) cuyos nombres tengan significado. Ejemplo:
IFS='|' read -r path1 path2 path3 path4 path5 ip path6 wtf1 wtf2 wtf3 extra < <(sed 's/ *| */|/g' <<< '/a585/app/data/CCN_text/CCN_split_files/ccn.email.list.file07 | /svr00c8/n585 | /a585/app/data/CCN_text | /a585/app/data/CCN_text | /a585/app/data/muttrc | 153.2.254.229 | /a001/odbi_land/ondemand/download/scriptload | DVLP | cmodappl | ondemand') echo "$ip" echo "$wtf3"
Notas específicas:
- Aquí usamos explícitamente
|
como delimitador. Cuando usamosread
, la nueva línea final (que aparece debido a cómo funcionan ciertas redirecciones y herramientas) no solo es inofensiva, sino que es obligatoria. - Agregué la
extra
variable. Si hay más campos de los esperados, se ocuparán los campos excesivosextra
. Sinextra
ellos afectarían$wtf3
. - Puedes
export
estas variables.
- Aquí usamos explícitamente
Si va a manipular archivos/transmisiones que contienen (muchos) registros en una forma
foo|bar|baz|…
(ofoo | bar | baz | …
similar), familiarícese conawk
.