Come posso leggere una variabile da un file?


68

Voglio inserire nel mio script un valore (stringa) che vorrei leggere da un file di testo.

Ad esempio, anziché:

echo "Enter your name"
read name

Voglio leggere una stringa da un altro file di testo, quindi l'interprete dovrebbe leggere la stringa dal file e non l'input dell'utente.


1
Che aspetto ha il tuo file di testo? L'intero file 1 è variabile o sono KEY=VALUEcoppie? Le soluzioni sono abbastanza diverse (se è la seconda, si applica la risposta di Takkat, la precedente Radu)
kiri,

1
@CiroSantilli non viene incrociato se è stato pubblicato da un altro utente, non esiste un "duplicato tra siti". L'unica cosa da evitare è la stessa domanda posta dallo stesso utente su siti diversi.
terdon

Risposte:


98

Per leggere le variabili da un file possiamo usare il comando sourceo ..

Supponiamo che il file contenga la seguente riga

MYVARIABLE="Any string"

possiamo quindi importare questa variabile usando

#!/bin/bash

source <filename>
echo $MYVARIABLE

17
Uno dei motivi per cui potresti non voler farlo in questo modo è perché tutto ciò che è dentro <filename>verrà eseguito nella tua shell, come rm -rf /, che potrebbe essere molto pericoloso.
Mark Ribau,

4
In ritardo alla festa, ma, no, non merita di essere segnato O come risposta. Questo genera un altro file sorgente bash che NON è quello richiesto dall'OP. Ha chiesto come leggere il contenuto di un FILE in una variabile. NON come eseguire un altro script che imposta una variabile . La risposta corretta è quella qui sotto. name = $ (cat "$ file").
HörmannHH,

2
OTOH, è la risposta alla domanda che ho posto a Google e Google mi ha portato qui. Tempi strani, eh?
Michael Terry,

1
Ottimo funziona anche per più variabili! Il punto di @MarkRibau è compreso, ma immagino che se si corregge il file in uno script diverso e si deve solo passarlo al di sopra e controllato.
madlymad,

1
Puoi usare sedper aggiungere localparole chiave e rendere lo script un po 'più sicuro e non inquinare il tuo ambito globale. Quindi all'interno di una funzione fai cat global_variables.sh | sed -e 's/^/local /' > local_variables.she poi usa . ./local_variables.sh. Qualunque cosa importiate nella funzione sarà disponibile solo in quella funzione. Si noti che presuppone global_variables.shche contenga solo una variabile per riga.
Nux,

55

Considerando che vuoi che tutto il contenuto del tuo file di testo sia mantenuto nella tua variabile, puoi usare:

#!/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

Oppure, in puro bash:

#!/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

Non voglio visualizzare la variabile, voglio che questa variabile venga letta dallo script per ulteriori elaborazioni. Ho provato Awk che legge riga per riga.
user208413

1
Ok, cancella echo $name . Lo uso solo per test. Successivamente puoi usare la $namevariabile per ulteriori elaborazioni ovunque tu voglia nel tuo script.
Radu Rădeanu,

Non posso usarlo ovunque sia il mio script perché lo script non conosce il valore della variabile. Nel nostro caso il nome della variabile.
user208413

6
@ user208413 Il valore di $namevariabile è la stringa dal tuo file assegnata usando il cat $filecomando. Cosa non è chiaro o così difficile da capire?
Radu Rădeanu,

1
È ridondante usare una $filevariabile separata se la usi solo una volta per caricare la $namevariabile, basta usarecat /path/to/file
kiri

11

Dall'interno del tuo script puoi fare questo:

read name < file_containing _the_answer

Puoi persino farlo più volte, ad esempio in un ciclo

while read LINE; do echo "$LINE"; done < file_containing_multiple_lines

o per un file con più elementi su ciascuna riga. . . grep -v ^ # file | mentre leggi abc; echo a = $ ab = $ bc = $ c; fatto
gaoithe

Questo legge l'intera riga di un file, non una variabile dichiarata all'interno del file.
belvederef

7

Un modo alternativo per farlo sarebbe semplicemente reindirizzare l'input standard al tuo file, dove hai tutto l'input dell'utente nell'ordine previsto dal programma. Ad esempio, con il programma (chiamato 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?"

e il file di input (chiamato input.in)

Tomas
26

potresti eseguirlo dal terminale in uno dei due modi seguenti:

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

e equivarrebbe semplicemente a eseguire lo script e inserire i dati manualmente - stamperebbe la riga "Ciao Tomas. Hai 26 anni, vero?".

Come Radu Rădeanu ha già suggerito , è possibile utilizzare catall'interno del proprio script per leggere il contenuto di un file in una versione disponibile; in tal caso, è necessario che ciascun file contenga solo una riga, con solo il valore desiderato per quella specifica variabile. Nell'esempio di cui sopra, si sarebbe dividere il file di input in uno con il nome (ad esempio, name.in) e una con l'età (ad esempio, age.in), e cambiare l' read namee read agelinee per name=$(cat name.in) e age=$(cat age.in)rispettivamente.


Ho il seguente script: vh = awk "NR == 3 {print; exit}" /var/www/test/test.txt con questo ho letto la riga 3 dal file di testo chiamato test.txt. Una volta che ottengo una stringa, voglio usare questa stringa come input per la creazione di una directory
user208413,

1
Cambialo in vh=$(awk "NR==3 {print;exit}" /var/www/test.txt). Avrai quindi la stringa salvata in variabile $vh, quindi puoi usarla in questo modo: mkdir "/var/www/$vh"- questo creerà una cartella con il nome specificato all'interno / var / www.
Tomas Aschan,

L'ho fatto in questo modo ma non riesco ancora a creare la cartella :(
user208413,

@ user208413: quali messaggi di errore ricevi? "Non funziona" non è, purtroppo, una descrizione del problema molto utile ...
Tomas Aschan,


3
name=$(<"$file") 

Da man bash:1785, questa sostituzione di comando è equivalente name=$(cat "$file")ma più veloce.



0

Se si desidera utilizzare più stringhe, è possibile utilizzare:

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

O

Se si desidera che l'utente indichi il file

read -e "Specify path to variable(s): " path;
for p in 'cat "$path"';
do echo "$p" ............................

0
#! /bin/bash
#  (GPL3+) Alberto Salvia Novella (es20490446e)


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

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


variableInFile ${@}

0

Lo uso per ottenere una singola variabile da un file

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

Quando GET_VARnon viene trovato ${FILE}, sarà vuoto anziché causare un errore grazie a || true.

Usa grep -Pche è in GNU grep ma non è predefinito in tutto grep al momento della stesura di questo.


Questo non sembra funzionare per me. Il $ iniziale genera un errore per il personaggio illegale
ginna,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.