Работа с огромными файлами в VIM

108

Я попытался открыть в VIM огромный (~ 2 ГБ) файл, но он задохнулся. На самом деле мне не нужно редактировать файл, просто эффективно прыгайте.

Как я могу работать с очень большими файлами в VIM?

hoju
источник
1
Вот похожий вопрос .
GeoAvila,
5
Vim должен быть в порядке, пока вы :set binaryсначала ...
ephemient
1
Это хорошая цель для новой файловой системы fuse! splitfs или что-то в этом роде ... Мне это нравится!
Rodrigo
1
Слишком поздно ... это уже существует: sourceforge.net/projects/joinsplitfs
Родриго
5
Вам нужен пейджер, а не редактор, сэр! См. Ответ Джима ниже.
Лестер Чунг

Ответы:

85

Сегодня мне нужно было отредактировать файл размером 12 ГБ. Плагин vim LargeFile у меня не работал. Он по-прежнему израсходовал всю мою память, а затем напечатал сообщение об ошибке :-(. Я не мог использовать hexedit ни для одного из них, так как он не может ничего вставить, просто перезаписать. Вот альтернативный подход:

Вы разделяете файл, редактируете части, а затем повторно объединяете его. Однако вам все равно нужно вдвое больше дискового пространства.

  • Найдите что-нибудь, окружающее строку, которую вы хотите отредактировать:

    grep -n 'something' HUGEFILE | head -n 1
    
  • Извлеките этот диапазон файла. Скажем, строки, которые вы хотите отредактировать, находятся в строках 4 и 5. Затем выполните:

    sed -n -e '4,5p' -e '5q' HUGEFILE > SMALLPART
    
    • Параметр -nнеобходим для подавления поведения sed по умолчанию для печати всего.
    • 4,5p печатает строки 4 и 5
    • 5q прерывает sed после обработки строки 5
  • Редактируйте SMALLPARTс помощью вашего любимого редактора.

  • Объедините файл:

    (head -n 3 HUGEFILE; cat SMALLPART; sed -e '1,5d' HUGEFILE) > HUGEFILE.new 
    
    • то есть: выберите все строки перед отредактированными строками из HUGEFILE (в данном случае это верхние 3 строки), объедините их с отредактированными строками (в данном случае строки 4 и 5) и используйте этот объединенный набор строк для замены эквивалент (в данном случае 5 верхних строк) в HUGEFILE и записать все это в новый файл.

    HUGEFILE.newтеперь будет ваш отредактированный файл, вы можете удалить оригинал HUGEFILE.

Florian
источник
30

Этот вопрос повторялся много лет. (Числа продолжают меняться, но концепция та же: как просматривать или редактировать файлы, размер которых превышает размер памяти?)

Очевидно, moreили lessэто хороший подход к простому чтению файлов - lessдаже предлагаетvi , как привязки для прокрутки и поиска.

Freshmeat поиск на «большие файлы» предполагает , что два редактора будут особенно подходят для ваших нужд.

Один из них: lfhex ... большой шестнадцатеричный редактор файлов (который зависит от Qt). Это, очевидно, предполагает использование графического интерфейса.

Другой, казалось бы, подходит для использования в консоли: hed ... и он утверждает, что имеет vim-подобный интерфейс (включая exрежим?).

Я уверен, что видел другие редакторы для Linux / UNIX, которые могли листать файлы, не загружая их в память целиком. Однако я не помню их имен. Я делаю этот ответ «вики», чтобы побудить других добавлять свои ссылки на таких редакторов. (Да, я знаком со способами решения проблемы с помощью splitи cat; но я думаю о редакторах, особенно о редакторах console / curses, которые могут обойтись без этого и сэкономить нам время / задержки и накладные расходы на дисковое пространство, которые влекут за собой такие подходы) .

Джим Деннис
источник
23

Поскольку вам не нужно фактически редактировать файл:

  1. view(или vim -R) должны достаточно хорошо работать с большими файлами.
  2. Или вы можете использовать moreилиless
ChssPly76
источник
Под «дросселями» вы имеете в виду, что нужно время, чтобы открыться? Или вообще вылетает? На моем не совсем недавнем Linux-компьютере требуется чуть более 4 минут, чтобы открыть файл размером 2,7 ГБ view(только что попробовал и рассчитал). Конечно, это не совсем мгновенно, но работает.
ChssPly76
Да это глохнет. Я уверен, что если бы я дождался, он в конце концов откроется. Я использовал меньше, потому что он открывается сразу, и я привык к навигации.
hoju
9

Я написал небольшой сценарий на основе ответа Флориана, в котором используется nano (мой любимый редактор):

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

Используйте это так:

sh hfnano yourHugeFile 3 8

В этом примере nano откроет строки с 3 по 8, вы можете их отредактировать, а когда вы сохраните и закроете, эти строки в огромном файле будут автоматически перезаписаны вашими сохраненными строками.

BT
источник
3

У меня была та же проблема, но это был дамп mysql объемом 300 ГБ, и я хотел избавиться от него DROPи изменить его CREATE TABLEна, CREATE TABLE IF NOT EXISTSпоэтому не хотел запускать два вызова sed. Я написал этот быстрый сценарий Ruby, чтобы обмануть файл этими изменениями:

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

Вызывается как

./mreplace.rb < foo.sql > foo_two.sql
Стив МакКоли
источник
Просто обратите внимание на запуск, чтобы запустить его, как требует chmod +x mreplace.rbсначала exe , вы также можете простоruby mreplace.rb ..
Smar
Спасибо, @Steeve McCauley! Хорошая работа. Именно то, что я искал, когда искал ответ на этот вопрос.
Nate Ritter
3

Для больших однострочных строк (печатает символы от 1до 99):

cut -c 1-99 filename
Дмитрий Сандалов
источник
2

Уже поздно, но если вы просто хотите перемещаться по файлу, не редактируя его, catвы тоже можете это сделать.

% cat filename | less

или, альтернативно, просто:

% less filename
чепуха
источник
8
Обратите внимание, что catсначала указывать файл безумно глупо, так как это либо означает, что файл полностью находится в памяти (так что lessможно искать файл), либо его нельзя искать вообще; catпросто дает статический выходной поток.
Smar
1

emacs очень хорошо работает с файлами размером до 100 мегабайт, я без особых проблем использовал его для файлов журналов.

Но обычно, когда у меня есть какая-то задача анализа, я считаю, что лучше написать сценарий на Perl.

Энди Росс
источник
0

Старая нить. Но тем не менее (каламбур :)).

 $less filename

less работает эффективно, если вы не хотите редактировать, а просто осмотритесь, что имеет место при проверке огромных файлов журнала.

Искать в less работает как vi

Самое приятное, что он доступен по умолчанию в большинстве дистрибутивов. Так что не будет проблем и для производственной среды.

глубокое погружение
источник
Поиск в текстовом файле объемом 650 МБ с меньшим размером оказался PITA. Использование vim с LargeFile прекрасно работает.
MariusCC
2
@MariusCC Значит, вы не работали с файлами размером более 2 ГБ, ваше очарование исчезнет из-за сбоя!
deepdive
-15

это старый, но используйте nano, vim или gvim

Shiroxx
источник
5
Эти инструменты ничего не делают для решения проблемы.
Дуг Вольфграм
1
nano заполняет память и умирает на мне.
Трынкевич Мариуш