Comment lire une variable d'un fichier?

68

Je veux insérer dans mon script une valeur (chaîne) que je lirais à partir d'un fichier texte.

Par exemple, au lieu de:

echo "Enter your name"
read name

Je veux lire une chaîne d'un autre fichier texte afin que l'interprète lise la chaîne du fichier et non la saisie de l'utilisateur.

utilisateur208413
la source
1
À quoi ressemble votre fichier texte? Le fichier entier 1 est-il une variable ou sont-ils des KEY=VALUEpaires? Les solutions sont très différentes (si c'est ce dernier, la réponse de Takkat s'applique, l'ancien Radu)
kiri
1
@CiroSantilli, si elle a été postée par un utilisateur différent, il n'y a pas de publication croisée, il n'existe pas de "duplication intersite". La seule chose à éviter est la même question posée par le même utilisateur sur différents sites.
terdon

Réponses:

98

Pour lire les variables d'un fichier, nous pouvons utiliser la commande sourceou ..

Supposons que le fichier contienne la ligne suivante

MYVARIABLE="Any string"

nous pouvons ensuite importer cette variable en utilisant

#!/bin/bash

source <filename>
echo $MYVARIABLE
Takkat
la source
17
Une des raisons pour lesquelles vous ne voudrez peut-être pas le faire de cette façon est que tout ce <filename>qui se trouve dans votre shell sera exécuté, par exemple rm -rf /, ce qui pourrait être très dangereux.
Mark Ribau
4
En retard pour la fête, mais, non, cela ne mérite pas d’être marqué OU comme réponse. Cette source un autre fichier source bash qui n'est pas ce que l'OP a demandé. Il a demandé comment lire le contenu d'un fichier dans une variable. PAS comment exécuter un autre script qui définit une variable . La réponse correcte est celle ci-dessous. name = $ (cat "$ file").
HörmannHH
2
OTOH, c'est la réponse à la question que j'ai posée à Google et que Google m'a amené ici. Des temps bizarres, hein?
Michael Terry
1
Excellent fonctionne également pour plusieurs variables! Le point de @MarkRibau est compris, mais j'imagine que si vous corrigez le fichier dans un script différent et que vous devez simplement le transmettre, il est fin et contrôlé.
madlymad
1
Vous pouvez utiliser sedpour ajouter un localmot clé et rendre le script un peu plus sûr et ne pas modifier votre portée globale. Donc, à l'intérieur d'une fonction, faites cat global_variables.sh | sed -e 's/^/local /' > local_variables.shpuis utilisez . ./local_variables.sh. Tout ce que vous importez dans la fonction ne sera disponible que dans cette fonction. Notez que cela suppose qu’il global_variables.shne contient qu’une variable par ligne.
Nux
55

Considérant que vous voulez que tout le contenu de votre fichier texte soit conservé dans votre variable, vous pouvez utiliser:

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

Ou, en pure 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
Radu Rădeanu
la source
Je ne veux pas afficher la variable, je veux que cette variable soit lue par le script pour un traitement ultérieur. J'ai essayé awk qui lit ligne par ligne.
user208413
1
Ok, supprimer echo $name . Je l'utilise juste pour le test. Ensuite, vous pouvez utiliser la $namevariable pour un traitement ultérieur où vous le souhaitez dans votre script.
Radu Rădeanu Le
Je ne peux pas l'utiliser n'importe où dans mon script car celui-ci ne connaît pas la valeur de la variable. Dans notre cas, le nom de la variable.
user208413
6
@ user208413 La valeur de $namevariable est la chaîne de votre fichier affectée à l'aide de la cat $filecommande. Qu'est-ce qui n'est pas clair ou si difficile à comprendre?
Radu Rădeanu
1
Il est redondant d'utiliser une $filevariable séparée si vous ne l'utilisez qu'une seule fois pour la charger $name, utilisez simplementcat /path/to/file
kiri
11

Dans votre script, vous pouvez faire ceci:

read name < file_containing _the_answer

Vous pouvez même le faire plusieurs fois, par exemple dans une boucle

while read LINE; do echo "$LINE"; done < file_containing_multiple_lines
thom
la source
ou pour un fichier avec plusieurs éléments sur chaque ligne. . . grep -v ^ # fichier | pendant la lecture abc; echo a = $ ab = $ bc = $ c; fait
Gaoithe
Ceci lit toute la ligne d'un fichier, pas une variable déclarée dans le fichier.
belvederef
7

Une autre solution consiste à rediriger simplement l’entrée standard dans votre fichier, où toutes les entrées de l’utilisateur sont dans l’ordre dans lequel il est attendu par le programme. Par exemple, avec le programme (appelé 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?"

et le fichier d'entrée (appelé input.in)

Tomas
26

vous pouvez l'exécuter depuis le terminal de l'une des deux manières suivantes:

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

et cela équivaudrait à exécuter le script et à entrer les données manuellement - la ligne "Bonjour Tomas. Vous avez 26 ans, n'est-ce pas?".

Comme Radu Rădeanu l' a déjà suggéré , vous pouvez utiliser catvotre script pour lire le contenu d'un fichier dans une variable. Dans ce cas, chaque fichier doit contenir une seule ligne, avec uniquement la valeur souhaitée pour cette variable spécifique. Dans l'exemple ci - dessus, vous souhaitez diviser le fichier d'entrée en un avec le nom ( par exemple, name.in) et une avec l'âge (disons age.in) et modifiez les read nameet read agelignes name=$(cat name.in) et age=$(cat age.in)respectivement.

Tomas Aschan
la source
J'ai le script suivant: vh = awk "NR == 3 {print; exit}" /var/www/test/test.txt avec ceci, je lis la ligne 3 du fichier texte nommé test.txt. Une fois que je reçois une chaîne, je souhaite utiliser cette chaîne comme entrée pour la création d'un répertoire.
user208413
1
Changer cela en vh=$(awk "NR==3 {print;exit}" /var/www/test.txt). Vous aurez alors la chaîne enregistrée dans variable $vh, vous pourrez donc l'utiliser comme suit: mkdir "/var/www/$vh"- cela créera un dossier avec le nom spécifié dans / var / www.
Tomas Aschan
J'ai fait de cette façon, mais il ne peut toujours pas créer le dossier :(
user208413
@ user208413: Quel (s) message (s) d'erreur recevez-vous? "Cela ne fonctionne pas" n'est malheureusement pas une description très utile du problème ...
Tomas Aschan
3
name=$(<"$file") 

A partir de man bash:1785, cette substitution de commande est équivalente à name=$(cat "$file")mais plus rapide.

enfer
la source
2

Réponse courte:

name=`cat "$file"`
Nedim
la source
0

Si vous souhaitez utiliser plusieurs chaînes, vous pouvez utiliser:

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

OU

Si vous voulez que l'utilisateur indique le fichier

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


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

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


variableInFile ${@}
Alberto Salvia Novella
la source
0

J'utilise ceci pour obtenir une seule variable d'un fichier

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

Quand GET_VARne se trouve pas dans ${FILE}ce sera vide plutôt que de causer une erreur grâce au || true.

Il utilise grep -Pce qui est dans GNU grep mais pas par défaut dans tous les grep au moment de l'écriture de ceci.

Eric Nemchik
la source
Cela ne semble pas fonctionner pour moi. Le $ initial jette une erreur pour le caractère illégal
ginna