Linux: extrem große Dateien bearbeiten

Wer unter Linux mit großen Dateien hantiert, kann nicht immer einen klassischen Editor zum Bearbeiten nutzen. Aktuelles Beispiel bei mir ist ein Datenbank-Dump, der 11 GB groß ist.

Anzeigen und Suchen

Zum Anzeigen von und Suchen in großen Dateien eignen sich die Tools head, tail, less und grep:

# head gibt per default die ersten 10 Zeilen einer Datei aus.
$ head datei.txt
# Die Anzahl der Zeilen ist aber konfigurierbar.
$ head -n 200 datei.txt

# tail gibt die letzten 10 Zeilen einer Datei aus, oder eine definierte
# Anzahl Zeilen.
$ tail -n 50 datei.txt

# less bietet sich an, wenn man erstmal einen Überblick erhalten möchte.
$ less datei.txt
# Zerstören Zeilenumbrüche die Übersicht? Mit -S lassen sich diese verhindern
$ less -S datei.txt

less lädt nicht die gesamte Datei in den RAM, was unter Umständen ja gar nicht möglich wäre, sondern liest die Datei ausschnittsweise ein, was bei sehr großen Dateien sehr hilfreich ist. Die Navigation innerhalb von less ist für Nutzer anderer Linux-Tools wie beispielsweise vim recht intuitiv. Hier ist eine kurze Übersicht über wichtige Kommandos:

G (= ⇧ + g) ans Ende springen
g an den Anfang springen
10% zu 10% der Datei springen
653 [Enter] zu Zeile 653 springen
25j springe 25 Zeilen nach unten
132k springe 132 Zeilen nach oben
/suchbegriff nach „suchbegriff“ suchen
n nächstes Suchergebnis
N vorheriges Suchergebnis
q less verlassen

Einige Funktionen sind nur verfügbar, wenn man die Zeilennummern berechnen lässt, was bei sehr großen Dateien recht lange dauern kann. Wie in der Statuszeile beschrieben, kann man die Kalkulation der Zeilennummern mit STRG+c abbrechen.

Das Suchen mit less ist dennoch mühsam, da nach jedem Ergebnis erst ein weiteres Ergebnis gesucht wird, was einige Zeit dauern kann. Will man sich direkt alle Ergebnisse anzeigen lassen eignet sich grep am besten.

# nach "Suchbegriff" suchen
$ grep "Suchbegriff" Datei
# mit einem regulären Ausdruck suchen
$ grep -E "<regulärer Ausdruck>" Datei
$ egrep "<regulärer Ausdruck>" Datei

Einige Optionen für die effiziente Arbeit mit grep sind beispielsweise:

-i Groß-/Kleinschreibung ignorieren
-r rekursiv suchen (Unterverzeichnisse einbeziehen)
-A 5 gebe nicht nur jedes Ergebnis aus, sondern jeweils auch die 5 nachfolgenden Zeilen
-B 10 wie -A, nur dass die vorherigen Zeilen vor dem jeweiligen Ergebnis angezeigt werden
-l nur den Dateinamen von Dateien angeben, die den Suchbegriff enthalten
-v gebe alle Zeilen aus, die den Suchbegriff nicht enthalten
-c zeige nur die Anzahl an Ergebnissen pro Datei
-n gebe Zeilennummern mit aus

Besonders der Parameter -n ist bei der Arbeit mit sehr großen Dateien hilfreich. Damit erhält man die entsprechende Zeilennummer und kann sich entweder mit less den genauen Kontext anschauen, oder aber die Zeile bearbeiten.

Einfügen, Bearbeiten und Ersetzen

Das ist die eigentliche „hohe Kunst“. Zum Bearbeiten sehr großer Dateien kann sed verwendet werden. Fangen wir klein an und fügen zwei kleine Zeilen an den Anfang und das Ende einer Datei an. Für letzteres braucht man nur echo:

# zwei Zeilen an das Ende der Datei anfügen
$ echo -e "Ende - Zeile 1\nEnde - Zeile 2" >> datei
# zwei Zeilen an den Anfang der Datei anfügen
$ sed -i "1i Anfang - Zeile 1\nAnfang - Zeile 2" datei

sed heißt so viel wie „stream editor“ und ist ein mächtiges Werkzeug aus der Unix-Welt. Der Parameter -i bewirkt, dass die Datei direkt bearbeitet und nicht nur der bearbeitete Inhalt ausgegeben wird. Weitere Parameter findet man in der Manpage zu sed.

Im oberen Beispiel mit sed sieht man, dass 1 die Nummer der Zeile ist, und „i“ die Funktion zum einfügen (insert); alles was folgt, wird als einzufügender Text interpretiert. Möchte man eine Zeile löschen würde das so aussehen:

# Zeile 123 löschen
$ sed -i "123d" datei
# Zeilen 1-100 löschen
$ sed -i "1,100d" datei
# alle Zeilen ab Zeile 30 löschen
$ sed -i "30,$d" datei

Möchte man Suchen und Ersetzen, kann man das ebenfalls mit sed machen:

# Suche ABC und ersetze durch EFG
$ sed -i "s/ABC/EFG/" datei
# Möchte man nicht nur den ersten Treffer in der Zeile, sondern alle
# ersetzen, geht das so:
$ sed -i "s/ABC/EFG/g" datei
# Außerdem kann man auch auf Zeilen(bereiche) einschränken
$ sed -i "15 s/ABC/EFG/g" datei
$ sed -i "30,100 s/ABC/EFG/g" datei
# Es gibt auch spezielle Zeichen:
#  $ - Ende der Datei
#  ^ - Anfang der Datei
$ sed -i "2,$ s/ABC/EFG/g" datei

Will man einfach ganze Zeilen ändern, gibt es das „c“-Kommando:

# Ersetzen der zweiten Zeile
$ sed -i "2c Neuer Inhalt der Zeile" datei
# oder man ändert alle Zeilen, in denen ein Suchbegriff vorkommt
$ sed -i "/pattern/c Dieser Eintrag wurde entfernt." datei

Weitere hilfreiche Informationen zu sed gibt es hier (englisch).

 

Wer einen Fehler findet oder weitere hilfreiche Hinweise hat, darf gern kommentieren.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.