2012-06-11 14 views
17

Wenn Sie in Java sicher sind, dass eine Datei sehr klein ist, können Sie die Methode readBytes() verwenden, um den Inhalt auf einmal zu lesen, anstatt ihn Zeile für Zeile oder mit Puffer zu lesen.Wie liest man den Dateiinhalt auf einmal in eine Variable?

Just in Shell-Skript fragen, ich weiß, wir so etwas wie tun:

while read line 
    do 
     echo $line 
     LINE = $line 
    done < "test.file" 
    echo $LINE 

Wenn mein test.file wie ist:

testline1 
testline2 
testline3 

Das gibt mir nur die letzte Zeile zu $LINE. $LINE enthält "testline3".

Meine Frage ist: Wie kann ich die ganze Datei mit mehreren Zeilen in eine einzige Variable lesen, so kann ich bekommen?

+1

'DATA = $ (cat-Datei)', Aber warum willst du das? Lies einfach die Datei, wann immer du den Inhalt brauchst! –

+1

Zwei Dinge, die nicht direkt mit Ihrer Frage zusammenhängen: Erstens funktioniert 'LINE = $ line' nicht wirklich; Der Raum um das Gleichheitszeichen macht es ungültig. Zweitens, wenn Sie Text manipulieren, den Sie im wahrsten Sinne des Wortes erhalten wollen, sollten Sie 'IFS' für Ihre Leseaufrufe auf Null setzen (andernfalls werden führende Leerzeichen auf jeder Zeile mit einem Atomkern versehen) und die' -r'-Option an 'read' übergeben und die '-E' Option zum' echo' (sonst werden alle umgekehrten Schrägstriche in Ihrer Datei die Sache durcheinander bringen). Sehen Sie meine Antwort unten zum Beispiel. –

+0

@MarkReed: Ich habe nie den Zweck von '-E' verstanden, da dies Bashs Standardverhalten für' echo' ist. –

Antwort

56

Verarbeiten Sie die Linien in der Schleife statt danach. Wenn Sie wirklich die Datei in einer Variablen müssen:

var=$(<file) 
+0

Können Sie uns auch erklären, was hier passiert? – sbhatla

+2

@sbhatla: Die Variable wird auf den Wert der Befehlsersetzung gesetzt, die eine Umleitung enthält, die den Inhalt der Datei liest. Es ist ähnlich wie 'var = $ (cat file)', aber es erfordert keine externe ausführbare Datei. –

8

Als weitere Option können Sie eine Reihe von Linien bauen. Wenn Sie mit bash 4+, können Sie die mapfile builtin verwenden:

mapfile -t lines <test.file 

Wenn Sie die Linien wollen auch ausgegeben werden als gespeicherte Sie so etwas wie dies tun könnte:

mapfile -t lines < <(tee /dev/tty <test.file) 

Dann "${lines[0]}" wird die erste Zeile der Datei sein, "${lines[1]}" die zweite, und so weiter. ${#lines[@]} wird die Anzahl der Zeilen sein; "${lines[@]}" wird das gesamte Array sein, während "${lines[*]}" die Linien zusammen mit Leerzeichen in einer großen Zeichenfolge sein wird.

Bei älteren Versionen von bash, können Sie das Array aufbauen können manuell:

lines=() 
while IFS= read -r line 
do 
    printf '%s\n' "$line" 
    lines+=("$line") 
done < test.file 
+1

Das wäre einfacher geschrieben als 'LINES + = (" $ line ")', nicht wahr? –

+0

Yup. Ich habe ein bisschen in 4 Jahren gelernt, so scheint es. Gut zu wissen.:) –

+0

Ich bezweifle es nicht für eine Sekunde :) –

10

Eine weitere Alternative ist das schöne mapfile builtin zu verwenden:

mapfile < test.file 
echo "${MAPFILE[@]}" 
+2

Es gibt keine man-Seite dafür, aber 'help mapfile' gibt weitere Informationen. Das Dienstprogramm wird standardmäßig die erste Zeile in Eintrag 0, die zweite Zeile in Eintrag 1 usw. einfügen. Sie möchten es wahrscheinlich auch mit der Option "-t" verwenden (Zeilenumbrüche entfernen). – parvus

+1

Beachten Sie, dass 'mapfile' in bash 4 eingeführt wurde und daher in'/bin/bash' unter OS X nicht verfügbar ist. Dies ist wahrscheinlich die letzte Bastion von bash 3, die wahrscheinlich in der Wildnis vorkommt, aber wahrscheinlich auch nicht aktualisiert wird aufgrund von Lizenzproblemen mit Apple und der neuen GPL. –

+1

Als Apple von Mac OS auf MacOS aktualisiert wurde, war bash 4.4 enthalten. – DopeGhoti

Verwandte Themen