Arbeiten mit großen Dateien in VIM


108

Ich habe versucht, eine riesige Datei (~ 2 GB) in VIM zu öffnen, aber sie ist verstopft. Ich muss die Datei nicht bearbeiten, sondern nur effizient herumspringen.

Wie kann ich mit sehr großen Dateien in VIM arbeiten?



5
Vim sollte in Ordnung sein, solange Sie :set binaryzuerst ...
kurzlebig

1
Dies ist ein gutes Ziel für ein neues Sicherungsdateisystem! splitfs oder so ähnlich ... ich bin begeistert !
Rodrigo

1
Zu spät ... das gibt es schon: sourceforge.net/projects/joinsplitfs
rodrigo

5
Sie brauchen einen Pager, keinen Editor, Sir! Siehe Jims Antwort unten.
Lester Cheung

Antworten:


85

Ich hatte heute eine 12-GB-Datei zum Bearbeiten. Das vim LargeFile-Plugin hat bei mir nicht funktioniert. Es hat immer noch meinen gesamten Speicher verbraucht und dann eine Fehlermeldung ausgegeben :-(. Ich konnte Hexedit auch nicht verwenden, da es nichts einfügen kann, sondern nur überschreiben. Hier ist ein alternativer Ansatz:

Sie teilen die Datei, bearbeiten die Teile und kombinieren sie neu. Sie benötigen jedoch immer noch doppelt so viel Speicherplatz.

  • Suchen Sie nach etwas, das die Linie umgibt, die Sie bearbeiten möchten:

    grep -n 'something' HUGEFILE | head -n 1
    
  • Extrahieren Sie diesen Bereich der Datei. Angenommen, die Zeilen, die Sie bearbeiten möchten, befinden sich in Zeile 4 und 5. Führen Sie dann folgende Schritte aus:

    sed -n -e '4,5p' -e '5q' HUGEFILE > SMALLPART
    
    • Die -nOption ist erforderlich, um das Standardverhalten von sed zu unterdrücken und alles zu drucken
    • 4,5p druckt die Zeilen 4 und 5
    • 5q bricht nach der Verarbeitung von Zeile 5 ab
  • Bearbeiten Sie SMALLPARTmit Ihrem Lieblingseditor.

  • Kombinieren Sie die Datei:

    (head -n 3 HUGEFILE; cat SMALLPART; sed -e '1,5d' HUGEFILE) > HUGEFILE.new 
    
    • dh: Wählen Sie alle Zeilen vor den bearbeiteten Zeilen aus der RIESIGEN DATEI (in diesem Fall die obersten 3 Zeilen) aus, kombinieren Sie sie mit den bearbeiteten Zeilen (in diesem Fall Zeilen 4 und 5) und verwenden Sie diesen kombinierten Satz von Zeilen, um die zu ersetzen äquivalent (in diesem Fall die obersten 5 Zeilen) in der RIESIGEN DATEI und schreiben Sie alles in eine neue Datei.

    HUGEFILE.newWird nun Ihre bearbeitete Datei, können Sie das Original löschen HUGEFILE.


30

Dies ist seit vielen Jahren eine wiederkehrende Frage. (Die Zahlen ändern sich ständig, aber das Konzept ist das gleiche: Wie kann ich Dateien anzeigen oder bearbeiten, die größer als der Speicher sind?)

Offensichtlich moreoder lesssind gute Ansätze zum bloßen Lesen der Dateien - lesssogar Angebote viwie Tastenkombinationen zum Scrollen und Suchen.

Eine Freshmeat- Suche nach "großen Dateien" legt nahe, dass zwei Editoren besonders für Ihre Anforderungen geeignet sind.

Eine wäre: lfhex ... ein Hex-Editor für große Dateien (der von Qt abhängt). Dies beinhaltet natürlich die Verwendung einer GUI.

Eine andere scheint für die Konsolennutzung geeignet zu sein: hed ... und behauptet, eine vimähnliche Oberfläche zu haben (einschließlich eines exModus?).

Ich bin sicher, ich habe andere Editoren für Linux / UNIX gesehen, die Dateien durchblättern konnten, ohne ihre Gesamtheit in den Speicher zu laden. Ich erinnere mich jedoch an keinen ihrer Namen. Ich mache diese Antwort zu einem "Wiki" -Eintrag, um andere zu ermutigen, ihre Links zu solchen Editoren hinzuzufügen. (Ja, ich bin mit Möglichkeiten vertraut, um das Problem mit splitund zu catumgehen. Ich denke jedoch an Editoren, insbesondere an Konsolen- / Fluch-Editoren, die darauf verzichten und uns die Zeit / Latenzen und den Speicherplatz sparen können, die solche Ansätze mit sich bringen.) .


23

Da Sie die Datei nicht wirklich bearbeiten müssen:

  1. view(oder vim -R) sollte bei großen Dateien einigermaßen gut funktionieren.
  2. Oder Sie können moreoder verwendenless

Mit "Drosseln" meinen Sie, dass das Öffnen eine Weile dauert? Oder tatsächlich abstürzt? Auf meiner nicht ganz so aktuellen Linux-Box dauert es etwas mehr als 4 Minuten, bis eine 2,7-GB-Datei geöffnet ist view(nur ausprobiert und zeitgesteuert). Zugegeben, das ist nicht gerade augenblicklich, aber es funktioniert.
ChssPly76

Ja, es bleibt stehen. Ich bin sicher, wenn ich warten würde, würde es sich irgendwann öffnen. Ich bin mit weniger gegangen, weil es sofort geöffnet wird und ich an die Navigation gewöhnt bin.
Hoju

9

Ich habe ein kleines Skript geschrieben, das auf Florians Antwort basiert und Nano (meinen Lieblingseditor) verwendet:

#!/bin/sh

if [ "$#" -ne 3 ]; then
  echo "Usage: $0 hugeFilePath startLine endLine" >&2
  exit 1
fi

sed -n -e $2','$3'p' -e $3'q' $1 > hfnano_temporary_file
nano hfnano_temporary_file
(head -n `expr $2 - 1` $1; cat hfnano_temporary_file; sed -e '1,'$3'd' $1) > hfnano_temporary_file2
cat hfnano_temporary_file2 > $1
rm hfnano_temporary_file hfnano_temporary_file2

Verwenden Sie es so:

sh hfnano yourHugeFile 3 8

In diesem Beispiel öffnet nano die Zeilen 3 bis 8, Sie können sie bearbeiten, und wenn Sie speichern und beenden, werden diese Zeilen in der riesigen Datei automatisch mit Ihren gespeicherten Zeilen überschrieben.


3

Ich hatte das gleiche Problem, aber es war ein 300 GB MySQL-Dump und ich wollte das loswerden DROPund zu wechseln CREATE TABLE, CREATE TABLE IF NOT EXISTSalso wollte ich nicht zwei Aufrufe von ausführen sed. Ich habe dieses schnelle Ruby-Skript geschrieben, um die Datei mit den folgenden Änderungen zu betrügen:

#!/usr/bin/env ruby

matchers={
    %q/^CREATE TABLE `foo`/ => %q/CREATE TABLE IF NOT EXISTS `foo`/,
    %q/^DROP TABLE IF EXISTS `foo`;.*$/ => "-- DROP TABLE IF EXISTS `foo`;"
}

matchers.each_pair { |m,r|
    STDERR.puts "%s: %s" % [ m, r ]
}

STDIN.each { |line|
    #STDERR.puts "line=#{line}"
    line.chomp!
    unless matchers.length == 0
        matchers.each_pair { |m,r|
            re=/#{m}/
            next if line[re].nil?
            line.sub!(re,r)
            STDERR.puts "Matched: #{m} -> #{r}"
            matchers.delete(m)
            break
        }
    end
    puts line
}

Aufgerufen wie

./mreplace.rb < foo.sql > foo_two.sql

Nur um zu beachten, um zu laufen, um es als Exe chmod +x mreplace.rbzuerst auszuführen , könnten Sie auch nurruby mreplace.rb ..
Smar

Danke @Steeve McCauley! Gute Arbeit. Genau das, wonach ich gesucht habe, als ich nach der Antwort auf diese Frage gesucht habe.
Nate Ritter


2

Es ist bereits spät, aber wenn Sie nur durch die Datei navigieren möchten, ohne sie zu bearbeiten, catkönnen Sie den Job auch erledigen.

% cat filename | less

oder alternativ einfach:

% less filename

8
Beachten Sie, dass cates wahnsinnig dumm ist, die Datei zuerst zu tönen, da dies entweder bedeutet, dass sich die Datei vollständig im Speicher befindet (also lessdie Datei suchen kann) oder überhaupt nicht gesucht werden kann. catgibt nur statischen Ausgabestream.
Smar

1

emacs funktioniert sehr gut mit Dateien bis zu 100 Megabyte. Ich habe es ohne allzu große Probleme für Protokolldateien verwendet.

Aber im Allgemeinen finde ich es besser, ein Perl-Skript zu schreiben, wenn ich eine Analyse-Aufgabe habe.


0

Alter Faden. Aber trotzdem (Wortspiel :)).

 $less filename

Weniger funktioniert effizient, wenn Sie nicht bearbeiten und sich nur umschauen möchten, was bei der Prüfung großer Protokolldateien der Fall ist.

Suche in weniger Werken wie vi

Das Beste daran ist, dass es in den meisten Distributionen standardmäßig verfügbar ist. Dies ist also auch für die Produktionsumgebung kein Problem.


Die Suche in einer 650-MB-Textdatei mit weniger erwies sich als PITA. Die Verwendung von vim mit LargeFile funktioniert wie ein Zauber.
MariusCC

2
@MariusCC Dann haben Sie nicht mit mehr als 2 GB Dateien gearbeitet, Ihr Charme wird mit dem Absturz verblassen!
Deepdive

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.