Praca z dużymi plikami w VIM


108

Próbowałem otworzyć ogromny (~ 2 GB) plik w VIM, ale się zaciął. Właściwie nie muszę edytować pliku, po prostu sprawnie skaczę.

Jak mogę pracować z bardzo dużymi plikami w VIM?



5
Vim powinien być w porządku, o ile :set binarynajpierw ...
ephemient,

1
To dobry cel dla nowego systemu plików fuse! splitfs czy coś w tym stylu ... Lubię to!
rodrigo

1
Za późno ... to już istnieje: sourceforge.net/projects/joinsplitfs
rodrigo.

5
Potrzebujesz pagera, a nie redaktora! Zobacz odpowiedź Jima poniżej.
Lester Cheung

Odpowiedzi:


85

Miałem dziś do edycji plik 12 GB. Wtyczka vim LargeFile nie działała dla mnie. Nadal zużywał całą moją pamięć, a następnie wyświetlał komunikat o błędzie :-(. Nie mogłem też użyć hexedit, ponieważ nie może niczego wstawić, po prostu nadpisać. Oto alternatywne podejście:

Podziel plik, edytuj części, a następnie ponownie go połączysz. Jednak nadal potrzebujesz dwa razy więcej miejsca na dysku.

  • Wyszukaj coś otaczającego linię, którą chcesz edytować:

    grep -n 'something' HUGEFILE | head -n 1
    
  • Wyodrębnij ten zakres pliku. Powiedz, że wiersze, które chcesz edytować, znajdują się w wierszach 4 i 5. Następnie wykonaj:

    sed -n -e '4,5p' -e '5q' HUGEFILE > SMALLPART
    
    • Ta -nopcja jest wymagana do powstrzymania domyślnego zachowania seda podczas wypisywania wszystkiego
    • 4,5p drukuje linie 4 i 5
    • 5q przerywa sed po przetwarzaniu linii 5
  • Edytuj SMALLPARTza pomocą swojego ulubionego edytora.

  • Połącz plik:

    (head -n 3 HUGEFILE; cat SMALLPART; sed -e '1,5d' HUGEFILE) > HUGEFILE.new 
    
    • tj .: wybierz wszystkie wiersze przed edytowanymi wierszami z OGROMNEGO PLIKU (który w tym przypadku jest 3 górnymi wierszami), połącz go z edytowanymi wierszami (w tym przypadku wiersze 4 i 5) i użyj tego połączonego zestawu wierszy do zastąpienia odpowiednik (w tym przypadku górne 5 wierszy) w HUGEFILE i zapisz to wszystko do nowego pliku.

    HUGEFILE.newbędzie teraz edytowanym plikiem, możesz usunąć oryginał HUGEFILE.


30

To powracające pytanie od wielu lat. (Liczby się zmieniają, ale koncepcja jest taka sama: jak przeglądać lub edytować pliki, które są większe niż pamięć?)

Oczywiście morelub lesssą dobrym podejściem do zwykłego czytania plików - lessnawet oferują vitakie skróty klawiszowe do przewijania i wyszukiwania.

Freshmeat szukaj w „dużych plików” sugeruje, że dwie redaktorzy będą szczególnie dostosowane do Twoich potrzeb.

Jednym z nich byłby: lfhex ... duży edytor szesnastkowy plików (zależny od Qt). To oczywiście pociąga za sobą użycie GUI.

Inny wydaje się być odpowiedni do użycia na konsoli: hed ... i twierdzi, że ma viminterfejs podobny do a (w tymex tryb?).

Jestem pewien, że widziałem inne edytory dla systemu Linux / UNIX, które były w stanie przeglądać pliki bez ładowania ich całości do pamięci. Jednak nie pamiętam żadnego z ich nazwisk. Robię tę odpowiedź jako wpis typu "wiki", aby zachęcić innych do dodawania swoich linków do takich edytorów. (Tak, znam sposoby obejścia tego problemu za pomocą spliti cat; ale myślę o edytorach, zwłaszcza edytorach konsol / curses, które mogą się z tego obejść i zaoszczędzić nam czasu / opóźnień i narzutu miejsca na dysku, które pociągają za sobą takie podejścia) .


23

Ponieważ nie musisz faktycznie edytować pliku:

  1. view (lub vim -R ) powinien działać dość dobrze na dużych plikach.
  2. Możesz też użyć morelubless

Mówiąc „dławiki” masz na myśli, że otwarcie zajmuje trochę czasu? A może faktycznie się zawiesza? Otwarcie pliku 2,7 GB na moim niezbyt nowym Linuksie zajmuje nieco ponad 4 minuty view(właśnie wypróbowane i zmierzone w czasie). To prawda, to nie jest dokładnie natychmiastowe, ale działa.
ChssPly76

Tak, to się zatrzymuje. Jestem pewien, że gdybym czekał, w końcu się otworzy. Poszedłem z mniej, ponieważ otwiera się natychmiast i jestem przyzwyczajony do nawigacji.
hoju

9

Napisałem mały skrypt na podstawie odpowiedzi Floriana, który używa nano (mój ulubiony edytor):

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

Użyj tego w ten sposób:

sh hfnano yourHugeFile 3 8

W tym przykładzie nano otworzy linie od 3 do 8, możesz je edytować, a kiedy zapiszesz i wyjdziesz, te linie w ogromnym pliku zostaną automatycznie nadpisane twoimi zapisanymi liniami.


3

Miałem ten sam problem, ale był to zrzut mysql o pojemności 300 GB i chciałem się go pozbyć DROPi zmienić CREATE TABLEna, CREATE TABLE IF NOT EXISTSwięc nie chciałem uruchamiać dwóch wywołań sed. Napisałem ten szybki skrypt Ruby, aby oszukać plik z tymi zmianami:

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

Wywołane jak

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

Pamiętaj tylko o uruchomieniu, aby uruchomić go jako exe chmod +x mreplace.rb, możesz też po prosturuby mreplace.rb ..
Smar

Dzięki @Steeve McCauley! Dobra robota. Dokładnie tego szukałem szukając odpowiedzi na to pytanie.
Nate Ritter,


2

Jest już późno, ale jeśli chcesz po prostu nawigować po pliku bez jego edycji, catmożesz też wykonać to zadanie.

% cat filename | less

lub alternatywnie proste:

% less filename

8
Zwróć uwagę, że cattingowanie pliku w pierwszej kolejności jest szalenie głupie, ponieważ oznacza to, że plik byłby w całości w pamięci (więc lessmożna przeszukać plik) lub nie można go w ogóle znaleźć; catpo prostu daje statyczny strumień wyjściowy.
Smar

1

emacs działa bardzo dobrze z plikami do 100 megabajtów, użyłem go na plikach dziennika bez większych problemów.

Ale generalnie, kiedy mam jakieś zadanie analityczne, uważam, że napisanie skryptu w Perlu jest lepszym wyborem.


0

Stara nić. Niemniej jednak (kalambur :)).

 $less filename

less działa wydajnie, jeśli nie chcesz edytować i po prostu się rozejrzyj, co ma miejsce w przypadku sprawdzania dużych plików dziennika.

Szukaj w less działa jak vi

Najlepsze jest to, że jest domyślnie dostępny w większości dystrybucji. Więc nie będzie problemu również dla środowiska produkcyjnego.


Wyszukiwanie w pliku tekstowym 650MB z mniejszym okazał się być PITA. Używanie vim z LargeFile działa jak urok.
MariusCC

2
@MariusCC Więc nie pracowałeś z więcej niż 2 GB plików, Twój urok zniknie z awarią!
nurkowanie głębokie

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.