Necesito poder exportar algunas variables de un archivo para poder usarlo en mi script BASH. el contenido del archivo es algo como esto:
my.variable.var1=a-long-ling.with.lot_of_different:characters:and_numbers
my.variable.another.var2=another-long-ling.with.lot_of_different:characters:and_numbers
my.variable.number3=yet_another_long-ling.with.lot_of_different:characters:and_numbers
Primero intenté obtenerlo source
tal como está y recibí el mensaje de error que decía: command not found
. Intenté usar export
, lo que me dio un mensaje de error que decía: not a valid identifier
.
Creo que sólo puedo exportar si cambio mi variable de my.variable.var1
a my_variable_var1
.
Puedo hacer esto cortando la línea en =
y luego reemplazando todos .
los s con _
s y luego agregando las variables nuevamente.
Entonces mi pregunta es, ¿es posible cambiar?
my.variable.var1=a-long-ling.with.lot_of_different:characters:and_numbers
my.variable.another.var2=another-long-ling.with.lot_of_different:characters:and_numbers
my.variable.number3=yet_another_long-ling.with.lot_of_different:characters:and_numbers
a
my_variable_var1=a-long-ling.with.lot_of_different:characters:and_numbers
my_variable_another_var2=another-long-ling.with.lot_of_different:characters:and_numbers
my_variable_number3=yet_another_long-ling.with.lot_of_different:characters:and_numbers
¿Estás usando alguna de esas frases ingeniosas? Me encantaría usarlo, además de un buen aprendizaje.
Respuesta1
Con sed
:
sed -e :1 -e 's/^\([^=]*\)\./\1_/;t1'
Es decir, reemplace una secuencia de caracteres que no sea .
el comienzo de la línea seguida .
de esa misma secuencia y _
y repita el proceso hasta que ya no coincida.
Con awk
:
awk -F = -v OFS== '{gsub(/\./, "_", $1); print}'
Ahora, en caso de que el lado derecho de =
contenga caracteres especiales del shell ( \
"$&();'#~<>...`, espacio, tabulación, otros espacios en blanco...), es posible que desee citarlo. :
sed "s/'/'\\\\''/g;:1"'
s/^\([^=]*\)\./\1_/;t1'"
s/=/='/;s/\$/'/"
O:
awk -F = -v q="'" -v OFS== '
{gsub(q, q "\\" q q)
gsub(/\./, "_", $1)
$2 = q $2
print $0 q}'
Respuesta2
Usando bash
:
while IFS='=' read -r i j; do echo "${i//./_}=$j" ; done
Hemos utilizado un patrón de expansión de parámetros ${i//./_}
para reemplazar todas .
las s con _
s en el nombre de la variable.
Ejemplo:
$ cat file.txt
my.variable.var1=a-long-ling.with.lot_of_different:characters:and_numbers
my.variable.another.var2=another-long-ling.with.lot_of_different:characters:and_numbers
my.variable.number3=yet_another_long-ling.with.lot_of_different:characters:and_numbers
$ while IFS='=' read -r i j; do echo "${i//./_}=$j" ; done <file.txt
my_variable_var1=a-long-ling.with.lot_of_different:characters:and_numbers
my_variable_another_var2=another-long-ling.with.lot_of_different:characters:and_numbers
my_variable_number3=yet_another_long-ling.with.lot_of_different:characters:and_numbers
Respuesta3
Aquí está otro sed
:
sed 'h;s/\./_/g;G;s/=.*=/=/'
Éste hace solo dos sustituciones, independientemente del número de puntos que preceden al =
so con una entrada como:
my.var.an.other.var.with.many.dots=line.with.many:chars:and_numbers.and.stuff
el resultado es
my_var_an_other_var_with_many_dots=line.with.many:chars:and_numbers.and.stuff
Esto funciona bien cuando hay un =
carácter por línea (como en su entrada de muestra).
Un enfoque más genérico que siempre reemplaza solo hasta el primero =
(y solo si la línea contiene al menos uno =
) incluso si hay varios =
caracteres por línea:
sed '/=/{ # if line matches =
h # copy pattern space over the hold space
s/\./_/g # replace all . with =
G # append hold space content to pattern space
s/=.*\n[^=]*=/=/ # replace from the first = up to the first = after
}' # the newline character with a single =
o
sed -e '/=/{h;s/\./_/g;G;s/=.*\n[^=]*=/=/' -e '}'
entonces con una entrada como:
my.var.with.many.dots.but.no.equal.sign.and.stuff
my.var.with.many.dots=line.with.many:chars:numbers_and.stuff
other.var.with.many.dots=and.with.more.than=one.equal.sign=and.stuff
produce:
my.var.with.many.dots.but.no.equal.sign.and.stuff
my_var_with_many_dots=line.with.many:chars:numbers_and.stuff
other_var_with_many_dots=and.with.more.than=one.equal.sign=and.stuff