Wie lese ich eine Variable aus einer Datei?

68

Ich möchte in mein Skript einen Wert (String) einfügen, den ich aus einer Textdatei lesen würde.

Zum Beispiel anstelle von:

echo "Enter your name"
read name

Ich möchte eine Zeichenfolge aus einer anderen Textdatei lesen, sodass der Interpreter die Zeichenfolge aus der Datei und nicht die Benutzereingabe lesen sollte.

user208413
quelle
1
Wie sieht Ihre Textdatei aus? Ist die gesamte Datei 1 variabel oder sind sie KEY=VALUEPaare? Die Lösungen sind ganz anders (wenn es die letztere ist, gilt die Antwort von Takkat, die ehemalige Radu)
kiri
1
@CiroSantilli Es wird kein Crossposting durchgeführt, wenn es von einem anderen Benutzer durchgeführt wurde. Es gibt kein "Cross-Site-Duplikat". Das einzige, was vermieden werden sollte, ist die gleiche Frage, die von demselben Benutzer auf verschiedenen Websites gestellt wird.
Terdon

Antworten:

98

Um Variablen aus einer Datei zu lesen, können wir den Befehl sourceoder verwenden ..

Nehmen wir an, die Datei enthält die folgende Zeile

MYVARIABLE="Any string"

Diese Variable können wir dann mit importieren

#!/bin/bash

source <filename>
echo $MYVARIABLE
Takkat
quelle
16
Ein Grund, warum Sie dies möglicherweise nicht auf diese Weise tun möchten, ist, dass alles, was <filename>sich in Ihrer Shell befindet, in Ihrer Shell ausgeführt wird, z. B. rm -rf /, was sehr gefährlich sein kann.
Mark Ribau
3
Verspätet zur Party, aber nein, es verdient nicht, als Antwort ODER gekennzeichnet zu werden. Dies liefert eine weitere Bash-Quelldatei, nach der das OP NICHT gefragt hat. Er fragte, wie der Inhalt einer DATEI in eine Variable eingelesen werden könne. NICHT, wie man ein anderes Skript ausführt, das eine Variable setzt . Die richtige Antwort ist die unten stehende. name = $ (Katze "$ file").
HörmannHH
2
OTOH, es ist die Antwort auf die Frage, die ich google gestellt habe und google hat mich hierher gebracht. Seltsame Zeiten, was?
Michael Terry
1
Großartig funktioniert auch für mehrere Variablen! Der Punkt von @MarkRibau wird verstanden, aber ich denke, wenn Sie die Datei in einem anderen Skript korrigieren und sie nur über ihre feine und kontrollierte übergeben müssen.
Madlymad
1
Sie können ein Schlüsselwort sedhinzufügen localund das Skript ein bisschen sicherer machen, ohne Ihren globalen Geltungsbereich zu gefährden. Also drinnen eine Funktion machen cat global_variables.sh | sed -e 's/^/local /' > local_variables.shund dann benutzen . ./local_variables.sh. Was auch immer Sie in die Funktion importieren, ist nur in dieser Funktion verfügbar. Beachten Sie, dass davon ausgegangen wird, dass global_variables.shnur eine Variable pro Zeile enthalten ist.
Nux
55

Angenommen, Sie möchten, dass der gesamte Inhalt Ihrer Textdatei in Ihrer Variablen gespeichert wird, können Sie Folgendes verwenden:

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

Oder in reiner 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
quelle
Ich möchte die Variable nicht anzeigen, ich möchte, dass diese Variable vom Skript zur weiteren Verarbeitung gelesen wird. Ich habe awk ausprobiert, das Zeile für Zeile liest.
User208413
1
Ok, löschen echo $name . Ich benutze es nur zum Testen. Als nächstes können Sie die $nameVariable zur weiteren Verarbeitung an einer beliebigen Stelle in Ihrem Skript verwenden.
Radu Rădeanu
Ich kann es nicht überall in meinem Skript verwenden, da das Skript den Wert der Variablen nicht kennt. In unserem Fall der Variablenname.
User208413
6
@ user208413 Der Wert der $nameVariablen ist die Zeichenfolge aus Ihrer Datei, die mit dem cat $fileBefehl zugewiesen wurde . Was ist nicht klar oder so schwer zu verstehen?
Radu Rădeanu
1
Es ist überflüssig, eine separate $fileVariable zu verwenden, wenn Sie sie nur einmal zum Laden der $nameVariablen verwenden. Verwenden Sie einfachcat /path/to/file
kiri
11

In Ihrem Skript können Sie dies tun:

read name < file_containing _the_answer

Sie können dies sogar mehrmals tun, z. B. in einer Schleife

while read LINE; do echo "$LINE"; done < file_containing_multiple_lines
thom
quelle
oder für eine Datei mit mehreren Elementen in jeder Zeile. . . grep -v ^ # file | while read abc; Echo a = $ ab = $ bc = $ c; done
gaoithe
7

Eine Alternative dazu wäre, die Standardeingabe einfach in Ihre Datei umzuleiten. Dort haben Sie alle Benutzereingaben in der Reihenfolge, in der sie vom Programm erwartet werden. Zum Beispiel mit dem Programm (aufgerufen 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?"

und die Eingabedatei (aufgerufen input.in)

Tomas
26

Sie können dies auf zwei Arten vom Terminal aus ausführen:

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

und es wäre gleichbedeutend mit dem Ausführen des Skripts und dem manuellen Eingeben der Daten - es würde die Zeile "Hallo Tomas. Du bist 26 Jahre alt, oder?"

Wie Radu Rădeanu hat bereits vorgeschlagen , könnten Sie catin Ihrem Skript den Inhalt einer Datei in ein avariable zu lesen - in diesem Fall Sie jede Datei benötigen nur eine Zeile enthalten, nur mit dem Wert , den Sie für diese bestimmte Variable wollen. Im obigen Beispiel würden Sie die Eingabedatei in eine mit dem Namen (sagen wir, geteilt name.in) und eine mit dem Alter ( zum Beispiel age.in), und die ändern read nameund read ageZeilen name=$(cat name.in) und age=$(cat age.in)jeweils.

Tomas Aschan
quelle
Ich habe das folgende Skript: vh = awk "NR == 3 {print; exit}" /var/www/test/test.txt Damit habe ich Zeile 3 aus der Textdatei test.txt gelesen. Sobald ich eine Zeichenfolge erhalte, möchte ich diese Zeichenfolge als Eingabe zum Erstellen eines Verzeichnisses verwenden
user208413
1
Ändern Sie das zu vh=$(awk "NR==3 {print;exit}" /var/www/test.txt). Anschließend wird die Zeichenfolge in einer Variablen gespeichert $vh, sodass Sie sie folgendermaßen verwenden können: mkdir "/var/www/$vh"- Dadurch wird ein Ordner mit dem angegebenen Namen in / var / www erstellt.
Tomas Aschan
Ich habe auf diese Weise getan, aber es kann immer noch nicht den Ordner erstellen :(
user208413
@ user208413: Welche Fehlermeldung (en) erhalten Sie? "Es funktioniert nicht" ist leider keine sehr hilfreiche Problembeschreibung ...
Tomas Aschan
3
name=$(<"$file") 

Ab entspricht man bash:1785diese Befehlsersetzung name=$(cat "$file")jedoch einer schnelleren.

Höllenkind
quelle
2

Kurze Antwort:

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

Wenn Sie mehrere Zeichenfolgen verwenden möchten, können Sie Folgendes verwenden:

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

ODER

Wenn Sie möchten, dass der Benutzer die Datei angibt

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


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

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


variableInFile ${@}
Alberto Salvia Novella
quelle
0

Ich benutze dies, um eine einzelne Variable aus einer Datei zu erhalten

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

Wenn GET_VARes nicht gefunden ${FILE}wird, ist es leer, anstatt einen Fehler zu verursachen || true.

Es wird verwendet, grep -Pwas sich zum Zeitpunkt des Schreibens in GNU grep befindet, aber nicht standardmäßig in all grep.

Eric Nemchik
quelle
Das scheint bei mir nicht zu funktionieren. Das anfängliche $ wirft einen Fehler für illegale Zeichen
Ginna