Travailler avec des fichiers volumineux dans VIM


108

J'ai essayé d'ouvrir un énorme fichier (~ 2 Go) dans VIM mais cela s'est étouffé. Je n'ai pas vraiment besoin d'éditer le fichier, il suffit de sauter efficacement.

Comment puis-je travailler avec des fichiers très volumineux dans VIM?



5
Vim devrait être ok tant que vous d' :set binaryabord ...
éphémère

1
C'est une bonne cible pour un nouveau système de fichiers fuse! splitfs ou quelque chose comme ça ... je suis dedans!
rodrigo

1
Trop tard ... cela existe déjà: sourceforge.net/projects/joinsplitfs
rodrigo

5
Vous avez besoin d'un téléavertisseur, pas d'un éditeur monsieur! Voir la réponse de Jim ci-dessous.
Lester Cheung

Réponses:


85

J'avais un fichier de 12 Go à éditer aujourd'hui. Le plugin vim LargeFile ne fonctionnait pas pour moi. Il a encore utilisé toute ma mémoire et a ensuite imprimé un message d'erreur :-(. Je ne pouvais pas utiliser hexedit pour l'un ou l'autre, car il ne peut rien insérer, juste écraser. Voici une approche alternative:

Vous divisez le fichier, modifiez les parties, puis vous le recombinez. Cependant, vous avez toujours besoin de deux fois plus d'espace disque.

  • Grep pour quelque chose entourant la ligne que vous souhaitez modifier:

    grep -n 'something' HUGEFILE | head -n 1
    
  • Extrayez cette plage du fichier. Dites que les lignes que vous souhaitez modifier se trouvent aux lignes 4 et 5. Puis faites:

    sed -n -e '4,5p' -e '5q' HUGEFILE > SMALLPART
    
    • L' -noption est requise pour supprimer le comportement par défaut de sed pour tout imprimer
    • 4,5p imprime les lignes 4 et 5
    • 5q abandonne sed après la ligne de traitement 5
  • Modifiez à l' SMALLPARTaide de votre éditeur préféré.

  • Combinez le fichier:

    (head -n 3 HUGEFILE; cat SMALLPART; sed -e '1,5d' HUGEFILE) > HUGEFILE.new 
    
    • c'est-à-dire: choisissez toutes les lignes avant les lignes éditées dans HUGEFILE (qui dans ce cas sont les 3 premières lignes), combinez-les avec les lignes éditées (dans ce cas les lignes 4 et 5) et utilisez cet ensemble combiné de lignes pour remplacer le équivalent (dans ce cas, les 5 premières lignes) dans le fichier HUGEFILE et écrivez le tout dans un nouveau fichier.

    HUGEFILE.newsera maintenant votre fichier édité, vous pouvez supprimer l'original HUGEFILE.


30

C'est une question récurrente depuis de nombreuses années. (Les chiffres changent constamment, mais le concept est le même: comment afficher ou modifier des fichiers plus volumineux que la mémoire?)

De toute évidence, moreou lesssont de bonnes approches pour simplement lire les fichiers --- lessmême des offres vicomme des raccourcis clavier pour le défilement et la recherche.

Une recherche Freshmeat sur «gros fichiers» suggère que deux éditeurs seraient particulièrement adaptés à vos besoins.

L'un serait: lfhex ... un éditeur hexadécimal de gros fichiers (qui dépend de Qt). Celui-là, évidemment, implique l'utilisation d'une interface graphique.

Une autre semble convenir à une utilisation en console: hed ... et elle prétend avoir une viminterface de type-like (y compris un exmode?).

Je suis sûr que j'ai vu d'autres éditeurs pour Linux / UNIX capables de parcourir des fichiers sans charger leur intégralité en mémoire. Cependant, je ne me souviens d'aucun de leurs noms. Je fais de cette réponse une entrée "wiki" pour encourager les autres à ajouter leurs liens vers ces éditeurs. (Oui, je connais les moyens de contourner le problème en utilisant splitet cat; mais je pense aux éditeurs, en particulier aux éditeurs de console / curses qui peuvent se passer de cela et nous faire gagner du temps / des latences et de l'espace disque que ces approches impliquent) .


23

Comme vous n'avez pas besoin de modifier le fichier:

  1. view(ou vim -R) devrait fonctionner raisonnablement bien sur des fichiers volumineux.
  2. Ou vous pouvez utiliser moreouless

Par "étranglements", vous voulez dire qu'il faut un certain temps pour s'ouvrir? Ou se bloque réellement? Il faut un peu plus de 4 minutes sur ma boîte Linux pas si récente pour ouvrir un fichier de 2,7 Go view(juste essayé et chronométré). Certes, ce n'est pas exactement instantané, mais cela fonctionne.
ChssPly76

Ouais ça cale. Je suis sûr que si j'attendais, il s'ouvrirait éventuellement. J'y suis allé avec moins car il s'ouvre immédiatement et je suis habitué à la navigation.
hoju

9

J'ai écrit un petit script basé sur la réponse de Florian qui utilise nano (mon éditeur préféré):

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

Utilisez-le comme ceci:

sh hfnano yourHugeFile 3 8

Dans cet exemple, nano ouvrira les lignes 3 à 8, vous pouvez les modifier, et lorsque vous enregistrez et quittez, ces lignes dans l'énorme fichier seront automatiquement écrasées par vos lignes enregistrées.


3

J'ai eu le même problème, mais c'était un vidage mysql de 300 Go et je voulais me débarrasser de DROPet changer CREATE TABLEen CREATE TABLE IF NOT EXISTSdonc je ne voulais pas exécuter deux invocations de sed. J'ai écrit ce script Ruby rapide pour duper le fichier avec ces modifications:

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

Invoqué comme

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

Juste à noter pour l'exécution, pour l'exécuter comme un exe nécessite d' chmod +x mreplace.rbabord, vous pouvez aussi simplementruby mreplace.rb ..
Smar

Merci @Steeve McCauley! Bon travail. Exactement ce que je recherchais en cherchant la réponse à cette question.
Nate Ritter

3

Pour les gros one-liners (imprime les caractères de 1à 99):

cut -c 1-99 filename

2

Il est déjà tard, mais si vous souhaitez simplement naviguer dans le fichier sans le modifier, vous catpouvez également faire le travail.

% cat filename | less

ou bien simple:

% less filename

8
Notez que catle fait de commencer par le fichier est incroyablement stupide, car cela signifie soit que le fichier serait entièrement en mémoire (donc lesspeut rechercher le fichier) ou qu'il ne peut pas être recherché du tout; catdonne juste un flux de sortie statique.
Smar du

1

emacs fonctionne très bien avec des fichiers dans les 100 mégaoctets, je l'ai utilisé sur des fichiers journaux sans trop de problèmes.

Mais généralement, lorsque j'ai une sorte de tâche d'analyse, je trouve que l'écriture d'un script perl est un meilleur choix.


0

Vieux fil. Mais néanmoins (jeu de mots :)).

 $less filename

less fonctionne efficacement si vous ne voulez pas modifier et simplement regarder autour de vous ce qui est le cas pour examiner d'énormes fichiers journaux.

Rechercher dans moins d'œuvres comme vi

Mieux encore, il est disponible par défaut sur la plupart des distributions. Ce ne sera donc pas non plus un problème pour l'environnement de production.


La recherche dans un fichier texte de 650 Mo avec moins s'est avérée être un PITA. Utiliser vim avec LargeFile fonctionne comme un charme.
MariusCC

2
@MariusCC Alors vous n'avez pas travaillé avec plus de 2 Go de fichiers, votre charme s'estompera avec le crash!
deepdive

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.