Ich möchte eine Datei lesen und sie in einer Variablen speichern, aber ich muss die Variable behalten und nicht nur die Datei ausdrucken. Wie kann ich das machen? Ich habe dieses Skript geschrieben, aber es ist nicht ganz das, was ich brauchte:
#!/bin/sh
while read LINE
do
echo $LINE
done <$1
echo 11111-----------
echo $LINE
In meinem Skript kann ich den Dateinamen als Parameter angeben, d.h. wenn die Datei z.B. "aaaa" enthält, würde es dies ausgeben:
aaaa
11111-----
Aber das gibt nur die Datei auf dem Bildschirm aus, und ich möchte sie in einer Variablen speichern! Gibt es eine einfache Möglichkeit, dies zu tun?
In plattformübergreifenden, kleinsten gemeinsamen Nenner sh
Sie verwenden:
#!/bin/sh
value=`cat config.txt`
echo "$value"
In bash
oder zsh
, um eine ganze Datei in eine Variable zu lesen, ohne cat
aufzurufen:
#!/bin/bash
value=$(<config.txt)
echo "$value"
In bash
oder zsh
cat
aufzurufen, um eine Datei zu schlürfen, würde als Useless Use of Cat betrachtet werden.
Beachten Sie, dass es nicht notwendig ist, die Befehlssubstitution in Anführungszeichen zu setzen, um Zeilenumbrüche zu erhalten.
Siehe: Bash Hacker's Wiki - Befehlssubstitution - Spezialitäten.
zwei wichtige Fallstricke
die in den anderen Antworten bisher ignoriert wurden:
Entfernen von Zeilenumbrüchen aus der Befehlserweiterung
Dies ist ein Problem für den:
value="$(cat config.txt)"
Lösungen, aber nicht für Lösungen, die auf "Lesen" basieren.
Bei der Befehlsexpansion werden nachstehende Zeilenumbrüche entfernt:
S="$(printf "a\n")"
printf "$S" | od -tx1
Gibt aus:
0000000 61
0000001
Dies bricht die naive Methode des Lesens aus Dateien:
FILE="$(mktemp)"
printf "a\n\n" > "$FILE"
S="$(<"$FILE")"
printf "$S" | od -tx1
rm "$FILE"
POSIX-Umgehung: Fügen Sie ein zusätzliches Zeichen an die Befehlserweiterung an und entfernen Sie es später:
S="$(cat $FILE; printf a)"
S="${S%a}"
printf "$S" | od -tx1
Gibt aus:
0000000 61 0a 0a
0000003
Fast POSIX-Umgehung: ASCII-Kodierung. Siehe unten.
NUL-Zeichen entfernen
Es gibt keine vernünftige Bash-Methode, um NUL-Zeichen in Variablen zu speichern.
Dies betrifft sowohl Expansions- als auch "Read"-Lösungen, und ich kenne keinen guten Workaround dafür.
Beispiel:
printf "a\0b" | od -tx1
S="$(printf "a\0b")"
printf "$S" | od -tx1
Ausgaben:
0000000 61 00 62
0000003
0000000 61 62
0000002
Ha, unser NUL ist weg!
Umgehungen:
ASCII kodieren. Siehe unten.
Bash-Erweiterung $""
Literale verwenden:
S=$"a\0b"
printf "$S" | od -tx1
Funktioniert nur für Literale, also nicht zum Lesen aus Dateien.
Abhilfe für die Fallstricke
Speichern Sie eine uuencode base64 kodierte Version der Datei in der Variablen und dekodieren Sie sie vor jeder Verwendung:
FILE="$(mktemp)"
printf "a\0\n" > "$FILE"
S="$(uuencode -m "$FILE" /dev/stdout)"
uudecode -o /dev/stdout <(printf "$S") | od -tx1
rm "$FILE"
Ausgabe:
0000000 61 00 0a
0000003
uuencode und udecode sind POSIX 7, aber nicht in Ubuntu 12.04 standardmäßig (sharutils
Paket)... Ich sehe keine POSIX 7 Alternative für die Bash Prozess <()
Substitutionserweiterung außer dem Schreiben in eine andere Datei...
Natürlich ist das langsam und unbequem, also ist die wirkliche Antwort wohl: Verwenden Sie keine Bash, wenn die Eingabedatei NUL-Zeichen enthalten kann.