Trabajar con archivos enormes en VIM

108

Intenté abrir un archivo enorme (~ 2GB) en VIM pero se ahogó. En realidad, no necesito editar el archivo, simplemente saltar de manera eficiente.

¿Cómo puedo trabajar con archivos muy grandes en VIM?

hoju
fuente
1
He aquí una pregunta similar .
GeoAvila
5
Vim debería estar bien siempre y cuando :set binaryprimero ...
ephemient
1
¡Este es un buen objetivo para un nuevo sistema de archivos fusible! splitfs o algo así ... ¡Me gusta!
rodrigo
1
Demasiado tarde ... esto ya existe: sourceforge.net/projects/joinsplitfs
rodrigo
5
¡Necesita un buscapersonas, no un editor, señor! Vea la respuesta de Jim a continuación.
Lester Cheung

Respuestas:

85

Tenía un archivo de 12 GB para editar hoy. El complemento vim LargeFile no funcionó para mí. Todavía usó toda mi memoria y luego imprimió un mensaje de error :-(. No pude usar hexedit para ninguno de los dos, ya que no puede insertar nada, solo sobrescribir. Aquí hay un enfoque alternativo:

Divide el archivo, edita las partes y luego lo recombina. Sin embargo, todavía necesita el doble de espacio en disco.

  • Grep para algo alrededor de la línea que le gustaría editar:

    grep -n 'something' HUGEFILE | head -n 1
    
  • Extraiga ese rango del archivo. Digamos que las líneas que desea editar están en la línea 4 y 5. Luego haga lo siguiente:

    sed -n -e '4,5p' -e '5q' HUGEFILE > SMALLPART
    
    • Se -nrequiere la opción para suprimir el comportamiento predeterminado de sed para imprimir todo
    • 4,5p imprime las líneas 4 y 5
    • 5q aborta sed después de la línea de procesamiento 5
  • Edite SMALLPARTcon su editor favorito.

  • Combinar el archivo:

    (head -n 3 HUGEFILE; cat SMALLPART; sed -e '1,5d' HUGEFILE) > HUGEFILE.new 
    
    • es decir, seleccione todas las líneas antes de las líneas editadas del HUGEFILE (que en este caso son las 3 líneas superiores), combínelas con las líneas editadas (en este caso las líneas 4 y 5) y use este conjunto combinado de líneas para reemplazar el equivalente (en este caso, las 5 líneas superiores) en el HUGEFILE y escríbalo todo en un nuevo archivo.

    HUGEFILE.newahora será su archivo editado, puede eliminar el original HUGEFILE.

Florian
fuente
30

Ésta ha sido una pregunta recurrente durante muchos años. (Los números siguen cambiando, pero el concepto es el mismo: ¿cómo veo o edito archivos que son más grandes que la memoria?)

Obviamente, moreo lessson buenos enfoques para simplemente leer los archivos, lessincluso ofrecen vicombinaciones de teclas para desplazarse y buscar.

Una búsqueda de Freshmeat en "archivos grandes" sugiere que dos editores se adaptarían particularmente a sus necesidades.

Uno sería: lfhex ... un editor hexadecimal de archivos grandes (que depende de Qt). Ese, obviamente, implica el uso de una GUI.

Otro parecería ser adecuado para el uso de la consola: hed ... y afirma tener una viminterfaz similar (¿incluye un exmodo?).

Estoy seguro de que he visto otros editores para Linux / UNIX que pudieron desplazarse por los archivos sin cargarlos por completo en la memoria. Sin embargo, no recuerdo ninguno de sus nombres. Estoy haciendo de esta respuesta una entrada "wiki" para animar a otros a agregar sus enlaces a dichos editores. (Sí, estoy familiarizado con las formas de solucionar el problema usando splity cat; pero estoy pensando en editores, especialmente editores de consola / curses que pueden prescindir de eso y ahorrarnos el tiempo / latencias y la sobrecarga de espacio en disco que conllevan tales enfoques) .

Jim Dennis
fuente
23

Dado que no necesita editar el archivo:

  1. view(o vim -R) debería funcionar razonablemente bien en archivos grandes.
  2. O puedes usar moreoless
ChssPly76
fuente
¿Por "estranguladores" te refieres a que tarda un poco en abrirse? ¿O realmente se estrella? Se necesitan un poco más de 4 minutos en mi caja de Linux no tan reciente para abrir un archivo de 2.7GB view(solo probado y cronometrado). Por supuesto, eso no es exactamente instantáneo, pero funciona.
ChssPly76
Sí, se estanca. Estoy seguro de que si esperaba, eventualmente se abriría. Me he ido con menos porque se abre de inmediato y estoy acostumbrado a la navegación.
hoju
9

Escribí un pequeño guión basado en la respuesta de Florian que usa nano (mi 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

Úselo así:

sh hfnano yourHugeFile 3 8

En ese ejemplo, nano abrirá las líneas 3 a 8, puede editarlas, y cuando guarde y salga, esas líneas en el enorme archivo se sobrescribirán automáticamente con sus líneas guardadas.

BT
fuente
3

Tuve el mismo problema, pero era un volcado de mysql de 300 GB y quería deshacerme de DROPy cambiar CREATE TABLEa, CREATE TABLE IF NOT EXISTSpor lo que no quería ejecutar dos invocaciones de sed. Escribí este rápido script de Ruby para engañar al archivo con esos cambios:

#!/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
fuente
Solo para tener en cuenta para ejecutar, para ejecutarlo como lo requiere un exe chmod +x mreplace.rbprimero, también podría simplementeruby mreplace.rb ..
Smar
¡Gracias @Steeve McCauley! Buen trabajo. Exactamente lo que estaba buscando al buscar la respuesta a esta pregunta.
Nate Ritter
3

Para grandes frases de una sola línea (imprime caracteres de 1a 99):

cut -c 1-99 filename
DmitrySandalov
fuente
2

Ya es tarde, pero si solo desea navegar por el archivo sin editarlo, también catpuede hacer el trabajo.

% cat filename | less

o alternativamente simple:

% less filename
chepukha
fuente
8
Tenga en cuenta que catting el archivo primero es increíblemente estúpido, ya que significa que el archivo estaría completamente en la memoria (por lo que lesspuede buscar el archivo) o no se puede buscar en absoluto; catsolo da un flujo de salida estático.
Smar
1

emacs funciona muy bien con archivos de cientos de megabytes, lo he usado en archivos de registro sin demasiados problemas.

Pero generalmente cuando tengo algún tipo de tarea de análisis, creo que escribir un script en Perl es una mejor opción.

Andy Ross
fuente
0

Hilo antiguo. Pero sin embargo (juego de palabras :)).

 $less filename

less funciona de manera eficiente si no desea editar y simplemente mirar a su alrededor, que es el caso de examinar archivos de registro enormes.

Buscar en menos obras como vi

La mejor parte es que está disponible de forma predeterminada en la mayoría de las distribuciones. Así que tampoco será un problema para el entorno de producción.

bucear profundo
fuente
La búsqueda en un archivo de texto de 650 MB con menos resultó ser un PITA. Usar vim con LargeFile funciona de maravilla.
MariusCC
2
@MariusCC Entonces no ha trabajado con archivos de más de 2 GB, ¡su encanto se desvanecerá con el bloqueo!
buceo profundo
-15

esto es antiguo, pero usa nano, vim o gvim

shiroxx
fuente
5
Estas herramientas no hacen nada para abordar el problema.
Doug Wolfgram
1
nano llena la memoria y muere en mí.
Trynkiewicz Mariusz