Trabalhar com arquivos enormes no VIM

108

Tentei abrir um arquivo enorme (~ 2 GB) no VIM, mas engasgou. Na verdade, não preciso editar o arquivo, apenas pular de maneira eficiente.

Como posso trabalhar com arquivos muito grandes no VIM?

hoju
fonte
1
Aqui está uma pergunta semelhante .
GeoAvila
5
O Vim deve ficar bem desde que você :set binaryprimeiro ...
efêmero
1
Este é um bom alvo para um novo sistema de arquivos fusível! splitfs ou algo parecido ... Estou nisso!
rodrigo
1
Tarde demais ... isso já existe: sourceforge.net/projects/joinsplitfs
rodrigo
5
Você precisa de um pager, não de um editor, senhor! Veja a resposta de Jim abaixo.
Lester Cheung de

Respostas:

85

Eu tinha um arquivo de 12 GB para editar hoje. O plugin vim LargeFile não funcionou para mim. Ele ainda usou toda a minha memória e, em seguida, imprimiu uma mensagem de erro :-(. Não consegui usar hexedit para nenhum dos dois, pois ele não pode inserir nada, apenas substituir. Aqui está uma abordagem alternativa:

Você divide o arquivo, edita as partes e então o recombina. Você ainda precisa de duas vezes o espaço em disco.

  • Pesquise algo ao redor da linha que você gostaria de editar:

    grep -n 'something' HUGEFILE | head -n 1
    
  • Extraia esse intervalo do arquivo. Digamos que as linhas que você deseja editar estejam nas linhas 4 e 5. Em seguida, faça:

    sed -n -e '4,5p' -e '5q' HUGEFILE > SMALLPART
    
    • A -nopção é necessária para suprimir o comportamento padrão do sed para imprimir tudo
    • 4,5p imprime as linhas 4 e 5
    • 5q aborta o sed após a linha de processamento 5
  • Edite SMALLPARTusando seu editor favorito.

  • Combine o arquivo:

    (head -n 3 HUGEFILE; cat SMALLPART; sed -e '1,5d' HUGEFILE) > HUGEFILE.new 
    
    • ou seja: escolha todas as linhas antes das linhas editadas do HUGEFILE (que neste caso são as 3 linhas principais), combine-as com as linhas editadas (neste caso as linhas 4 e 5) e use este conjunto combinado de linhas para substituir o equivalente (neste caso, as 5 primeiras linhas) no HUGEFILE e grave tudo em um novo arquivo.

    HUGEFILE.newagora será seu arquivo editado, você pode excluir o original HUGEFILE.

Florian
fonte
30

Esta tem sido uma questão recorrente por muitos anos. (Os números estão sempre mudando, mas o conceito é o mesmo: como faço para visualizar ou editar arquivos maiores do que a memória?)

Obviamente, moreou lesssão boas abordagens para meramente ler os arquivos --- lessaté ofertas vicomo atalhos de teclado para rolar e pesquisar.

Uma pesquisa do Freshmeat em "arquivos grandes" sugere que dois editores seriam particularmente adequados às suas necessidades.

Um seria: lfhex ... um grande editor hexadecimal de arquivo (que depende do Qt). Esse, obviamente, envolve o uso de uma GUI.

Outro parece ser adequado para uso em console: hed ... e afirma ter uma viminterface semelhante (incluindo um exmodo?).

Tenho certeza de que já vi outros editores para Linux / UNIX que conseguiram folhear os arquivos sem carregar totalmente na memória. No entanto, não me lembro de nenhum de seus nomes. Estou tornando esta resposta uma entrada de "wiki" para incentivar outras pessoas a adicionar seus links a esses editores. (Sim, estou familiarizado com as maneiras de contornar o problema usando splite cat; mas estou pensando em editores, especialmente editores de console / curses, que podem dispensar isso e nos poupar tempo / latências e sobrecarga de espaço em disco que tais abordagens acarretam) .

Jim Dennis
fonte
23

Já que você não precisa realmente editar o arquivo:

  1. view(ou vim -R) deve funcionar razoavelmente bem em arquivos grandes.
  2. Ou você pode usar moreouless
ChssPly76
fonte
Por "engasgamento" você quer dizer que demora um pouco para abrir? Ou realmente trava? Demora um pouco mais de 4 minutos na minha caixa Linux não tão recente para abrir um arquivo de 2.7 GB view(apenas experimentado e cronometrado). Concedido, isso não é exatamente instantâneo, mas funciona.
ChssPly76 de
Sim, ele para. Tenho certeza de que se eu esperasse, ele abriria eventualmente. Escolhi menos porque abre imediatamente e estou acostumado com a navegação.
hoju de
9

Escrevi um pequeno script baseado na resposta de Florian que usa nano (meu editor favorito):

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

Use-o assim:

sh hfnano yourHugeFile 3 8

Nesse exemplo, o nano abrirá as linhas de 3 a 8, você pode editá-las e, ao salvar e sair, essas linhas no arquivo enorme serão substituídas automaticamente pelas linhas salvas.

BT
fonte
3

Eu tive o mesmo problema, mas era um dump do mysql de 300 GB e eu queria me livrar do DROPe mudar CREATE TABLEpara, CREATE TABLE IF NOT EXISTSentão não queria executar duas invocações de sed. Escrevi este rápido script Ruby para enganar o arquivo com essas alterações:

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

Invocado como

./mreplace.rb < foo.sql > foo_two.sql
Steeve McCauley
fonte
Apenas para observação para execução, para executá-lo como um exe requer chmod +x mreplace.rbprimeiro, você também pode apenasruby mreplace.rb ..
Smar
Obrigado @Steeve McCauley! Bom trabalho. Exatamente o que eu procurava ao buscar a resposta para essa pergunta.
Nate Ritter
3

Para one-liners enormes (imprime caracteres de 1a 99):

cut -c 1-99 filename
DmitrySandalov
fonte
2

Já é tarde, mas se você quiser apenas navegar pelo arquivo sem editá-lo, catpode fazer o trabalho também.

% cat filename | less

ou alternativamente simples:

% less filename
Chepukha
fonte
8
Observe que verificar cato arquivo primeiro é insanamente estúpido, pois significa que o arquivo estaria totalmente na memória (portanto, lesspode procurar o arquivo) ou não pode ser procurado de forma alguma; catapenas fornece fluxo de saída estático.
Smar de
1

O emacs funciona muito bem com arquivos na casa dos 100 megabytes, usei-o em arquivos de log sem muitos problemas.

Mas geralmente, quando tenho algum tipo de tarefa de análise, acho que escrever um script perl é uma escolha melhor.

Andy Ross
fonte
0

Tópico antigo. Mas mesmo assim (trocadilho :)).

 $less filename

funciona menos eficientemente se você não quiser editar e apenas dar uma olhada, o que é o caso de examinar arquivos de log enormes.

Pesquisar em menos funciona como vi

Melhor parte, ele está disponível por padrão na maioria das distros. Portanto, não será problema para o ambiente de produção também.

mergulho profundo
fonte
Pesquisar em arquivo de texto de 650 MB com menos provou ser um PITA. Usar o vim com LargeFile funciona perfeitamente.
MariusCC
2
@MariusCC Então você não trabalhou com mais de 2 GB de arquivos, seu charme irá desaparecer com o travamento!
deepdive
-15

isso é antigo, mas use nano, vim ou gvim

shiroxx
fonte
5
Essas ferramentas não fazem nada para resolver o problema.
Doug Wolfgram
1
nano enche a memória e morre em mim.
Trynkiewicz Mariusz