¿Cómo leo una variable de un archivo?

68

Quiero insertar en mi script un valor (cadena) que leería de un archivo de texto.

Por ejemplo, en lugar de:

echo "Enter your name"
read name

Quiero leer una cadena de otro archivo de texto para que el intérprete lea la cadena del archivo y no la entrada del usuario.

usuario208413
fuente
1
¿Cómo se ve tu archivo de texto? ¿Es todo el archivo 1 variable o son KEY=VALUEpares? Las soluciones son bastante diferentes (si es la última, se aplica la respuesta de Takkat, la anterior Radu)
kiri
1
@CiroSantilli no tiene una posición cruzada si fue publicado por un usuario diferente, no existe un "duplicado entre sitios". Lo único que debe evitarse es la misma pregunta que hace el mismo usuario en diferentes sitios.
terdon

Respuestas:

98

Para leer variables de un archivo podemos usar el comando sourceo ..

Supongamos que el archivo contiene la siguiente línea

MYVARIABLE="Any string"

entonces podemos importar esta variable usando

#!/bin/bash

source <filename>
echo $MYVARIABLE
Takkat
fuente
16
Una razón por la que es posible que no desee hacerlo de esta manera es porque todo lo que esté dentro <filename>se ejecutará en su shell, por ejemplo rm -rf /, lo que podría ser muy peligroso.
Mark Ribau
3
Tarde a la fiesta, pero no, no merece ser marcado O como la respuesta. Esto genera otro archivo fuente bash que NO es lo que solicitó el OP. Preguntó cómo leer el contenido de un ARCHIVO en una variable. NO cómo ejecutar otro script que establece una variable . La respuesta correcta es la siguiente. nombre = $ (cat "$ archivo").
HörmannHH
2
OTOH, es la respuesta a la pregunta que le hice a Google y Google me trajo aquí. Tiempos extraños, ¿eh?
Michael Terry
1
¡Genial también funciona para múltiples variables! Se entiende el punto de @MarkRibau, pero supongo que si corrige el archivo en un script diferente y solo tiene que pasarlo por encima, está bien y controlado.
madlymad
1
Puede usar sedpara agregar localpalabras clave y hacer que el script sea un poco más seguro y no contaminar su alcance global. Así que dentro de una función hacer cat global_variables.sh | sed -e 's/^/local /' > local_variables.shy luego usar . ./local_variables.sh. Lo que importe en la función solo estará disponible en esa función. Tenga en cuenta que se supone que global_variables.shsolo contiene una variable por línea.
Nux
55

Teniendo en cuenta que desea que todo el contenido de su archivo de texto se mantenga en su variable, puede usar:

#!/bin/bash

file="/path/to/filename" #the file where you keep your string name

name=$(cat "$file")        #the output of 'cat $file' is assigned to the $name variable

echo $name               #test

O, en pura fiesta:

#!/bin/bash

file="/path/to/filename"     #the file where you keep your string name

read -d $'\x04' name < "$file" #the content of $file is redirected to stdin from where it is read out into the $name variable

echo $name                   #test
Radu Rădeanu
fuente
No quiero mostrar la variable, quiero que el script lea esta variable para su posterior procesamiento. He intentado awk que lee línea por línea.
user208413
1
Ok, borrar echo $name . Lo uso solo para prueba. A continuación, puede usar la $namevariable para su posterior procesamiento en cualquier lugar que desee en su secuencia de comandos.
Radu Rădeanu
No puedo usarlo en ninguna parte de mi script porque el script no conoce el valor de la variable. En nuestro caso el nombre de la variable.
user208413
66
@ user208413 El valor de la $namevariable es la cadena del archivo asignado mediante el cat $filecomando. ¿Qué no está claro o es tan difícil de entender?
Radu Rădeanu
1
Es redundante usar una $filevariable separada si solo la usa una vez para cargar la $namevariable, solo usecat /path/to/file
kiri
11

Desde su script puede hacer esto:

read name < file_containing _the_answer

Incluso puede hacer esto varias veces, por ejemplo, en un bucle

while read LINE; do echo "$LINE"; done < file_containing_multiple_lines
thom
fuente
o para un archivo con múltiples elementos en cada línea. . . grep -v ^ # archivo | mientras lee abc; hacer eco a = $ ab = $ bc = $ c; hecho
gaoithe
7

Una forma alternativa de hacer esto sería simplemente redirigir la entrada estándar a su archivo, donde tiene toda la entrada del usuario en el orden que espera el programa. Por ejemplo, con el programa (llamado script.sh)

#!/bin/bash
echo "Enter your name:"
read name
echo "...and now your age:"
read age

# example of how to use the values now stored in variables $name and $age
echo "Hello $name. You're $age years old, right?"

y el archivo de entrada (llamado input.in)

Tomas
26

puede ejecutar esto desde la terminal de una de las siguientes dos maneras:

$ cat input.in | ./script.sh
$ ./script.sh < input.in

y sería equivalente a simplemente ejecutar el script e ingresar los datos manualmente; imprimiría la línea "Hola Tomás. Tienes 26 años, ¿verdad?".

Como Radu Rădeanu ya ha sugerido , puede usar catdentro de su secuencia de comandos para leer el contenido de un archivo de manera disponible; en ese caso, necesita que cada archivo contenga solo una línea, con solo el valor que desea para esa variable específica. En el ejemplo anterior, debería dividir el archivo de entrada en uno con el nombre (por ejemplo, name.in) y otro con la edad (por ejemplo, age.in), y cambiar el read namey read agelíneas de name=$(cat name.in) y age=$(cat age.in)respectivamente.

Tomás Aschan
fuente
Tengo el siguiente script: vh = awk "NR == 3 {print; exit}" /var/www/test/test.txt con esto leí la línea 3 del archivo de texto llamado test.txt. Una vez que obtengo una cadena, quiero usar esta cadena como entrada para crear un directorio
user208413
1
Cambia eso a vh=$(awk "NR==3 {print;exit}" /var/www/test.txt). Luego tendrá la cadena guardada en variable $vh, para que pueda usarla así: mkdir "/var/www/$vh"- esto creará una carpeta con el nombre especificado dentro de / var / www.
Tomas Aschan
Lo he hecho de esta manera pero aún no puedo crear la carpeta :(
user208413
@ user208413: ¿Qué mensaje (s) de error recibe? "No funciona", lamentablemente, no es una descripción de problema muy útil ...
Tomas Aschan
3
name=$(<"$file") 

Desde man bash:1785, esta sustitución de comando es equivalente name=$(cat "$file")pero más rápida.

Hellork
fuente
2

Respuesta corta:

name=`cat "$file"`
nedim
fuente
0

Si desea utilizar varias cadenas, puede usar:

path="/foo/bar";
for p in `cat "$path"`;
do echo "$p" ....... (here you would pipe it where you need it) 

O

Si desea que el usuario indique el archivo

read -e "Specify path to variable(s): " path;
for p in 'cat "$path"';
do echo "$p" ............................
Jorge
fuente
0
#! /bin/bash
#  (GPL3+) Alberto Salvia Novella (es20490446e)


variableInFile () {
    variable=${1}
    file=${2}

    source ${file}
    eval value=\$\{${variable}\}
    echo ${value}
}


variableInFile ${@}
Alberto Salvia Novella
fuente
0

Lo uso para obtener una sola variable de un archivo

GET_VAR=$(grep --color=never -Po "^${GET_VAR}=\K.*" "${FILE}" || true)

Cuando GET_VARno se encuentre en ${FILE}él, estará en blanco en lugar de causar un error gracias a || true.

Utiliza el grep -Pque está en GNU grep pero no por defecto en todo grep al momento de escribir esto.

Eric Nemchik
fuente
Esto no parece funcionar para mí. Los $ iniciales arrojan un error por carácter ilegal
ginna