linea - Trabajando con archivos enormes en VIM
vim linux (10)
Dado que no necesita editar realmente el archivo:
Intenté abrir un archivo enorme (~ 2GB) en VIM pero se bloqueó. Realmente no necesito editar el archivo, solo saltar de manera eficiente.
¿Cómo puedo trabajar con archivos muy grandes en VIM?
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 archivo enorme se sobrescribirán automáticamente con sus líneas guardadas.
Esta 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, more
o less
son buenos métodos para simplemente leer los archivos, less
ofertas incluso vi
como combinaciones de teclas para desplazarse y buscar.
Una búsqueda Freshmeat en "archivos grandes" sugiere que dos editores serían especialmente adecuados para 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 interfaz similar a vim
(incluido un modo ex
?).
Estoy seguro de que he visto otros editores para Linux / UNIX que fueron capaces de navegar por los archivos sin cargar todo su contenido en la memoria. Sin embargo, no recuerdo ninguno de sus nombres. Hago de esta respuesta una entrada "wiki" para alentar a otros a agregar sus enlaces a dichos editores. (Sí, estoy familiarizado con las formas de solucionar el problema usando split
y cat
; pero estoy pensando en los editores, especialmente en los editores de consola / maldición, que pueden prescindir de eso y ahorrarnos el tiempo / latencias y el espacio en el disco que estos enfoques implicar).
Hilo viejo Pero sin embargo (juego de palabras :)).
$less filename
menos funciona de manera eficiente si no desea editar y solo mira a su alrededor, que es el caso para examinar grandes archivos de registro.
Buscar en menos obras como vi
La mejor parte, está disponible por defecto en la mayoría de las distribuciones. Así que no será un problema para el entorno de producción también.
Para líneas grandes (imprime caracteres del 1
al 99
):
cut -c 1-99 filename
Tenía un archivo de 12GB 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, simplemente sobrescribir. Aquí hay un enfoque alternativo:
Divides el archivo, editas las partes y luego lo recombinas. Sin embargo, todavía necesita el doble de espacio en disco.
Grep por algo que rodea la línea que te gustaría editar:
grep -n ''something'' HUGEFILE | head -n 1
Extrae ese rango del archivo. Supongamos 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
- La opción
-n
es necesaria 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 procesar la línea 5
- La opción
Edita
SMALLPART
usando tu editor favorito.Combina el archivo:
(head -n 3 HUGEFILE; cat SMALLPART; sed -e ''1,5d'' HUGEFILE) > HUGEFILE.new
- es decir: elija todas las líneas antes de las líneas editadas de 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 utilice este conjunto combinado de líneas para reemplazar el equivalente (en este caso, las 5 líneas superiores) en HUGEFILE y escríbalo en un nuevo archivo.
HUGEFILE.new
ahora será su archivo editado, puede eliminar elHUGEFILE
original.
Tuve el mismo problema, pero era un volcado de mysql de 300GB y quería deshacerme de DROP
y cambiar CREATE TABLE
para CREATE TABLE IF NOT EXISTS
por lo que no quería ejecutar dos invocaciones de sed
. Escribí este rápido script de Ruby para engañar el 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
Ya es tarde, pero si solo quieres navegar por el archivo sin editarlo, cat
puede hacer el trabajo.
% cat filename | less
o alternativamente simple:
% less filename
emacs funciona muy bien con archivos en cientos de megabytes, lo he usado en archivos de registro sin demasiados problemas.
Pero, en general, cuando tengo algún tipo de tarea de análisis, creo que escribir un guión de Perl es una mejor opción.
esto es viejo pero usa nano, vim o gvim