如何在 Vim 中处理大文件?

问题描述 投票:0回答:10

我尝试在 Vim 中打开一个巨大的(~2 GB)文件,但它卡住了。我实际上不需要编辑文件,只需高效地跳转即可。

如何在 Vim 中处理非常大的文件?

vim large-files
10个回答
93
投票

我今天有一个 12GB 的文件需要编辑。 vim LargeFile 插件对我不起作用。它仍然耗尽了我所有的内存,然后打印了一条错误消息:-(。我无法使用 hexedit,因为它不能插入任何内容,只需覆盖即可。这是另一种方法:

您拆分文件,编辑各个部分,然后重新组合。但您仍然需要两倍的磁盘空间。

  • Grep 查找您要编辑的行周围的内容:

    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
      在处理第 5 行后中止 sed
  • 使用您最喜欢的编辑器编辑

    SMALLPART

  • 合并文件:

    (head -n 3 HUGEFILE; cat SMALLPART; sed -e '1,5d' HUGEFILE) > HUGEFILE.new 
    
    • 即:从 HUGEFILE 中选取已编辑行之前的所有行(在本例中为前 3 行),将其与已编辑行(在本例中为第 4 行和第 5 行)合并,并使用这组组合行来替换HUGEFILE 中的等效内容(在本例中为前 5 行)并将其全部写入一个新文件。

    HUGEFILE.new
    现在将是您编辑的文件,您可以删除原始的
    HUGEFILE


31
投票

这是多年来反复出现的问题。 (数字不断变化,但概念是相同的:如何查看或编辑大于内存的文件?)

显然

more
less
是仅仅读取文件的好方法 ---
less
甚至提供
vi
之类的用于滚动和搜索的按键绑定。

对“大文件”进行Freshmeat搜索表明两个编辑器将特别适合您的需求。

一个是:lfhex ...一个大文件十六进制编辑器(取决于 Qt)。显然,这需要使用 GUI。

另一个似乎适合控制台使用:hed ...并且它声称有一个类似

vim
的界面(包括
ex
模式?)。

我确信我见过其他 Linux/UNIX 编辑器能够对文件进行分页,而无需将其全部加载到内存中。然而,我不记得他们的名字。我将此回复作为“wiki”条目,以鼓励其他人将链接添加到此类编辑器。 (是的,我熟悉使用

split
cat
解决该问题的方法;但我正在考虑编辑器,尤其是控制台/curses 编辑器,它们可以免除这些问题并节省我们的时间/延迟和磁盘空间这种方法所带来的开销)。


25
投票

因为您不需要实际编辑文件:

  1. view
    (或
    vim -R
    )应该在大文件上工作得相当好。
  2. 或者您可以使用
    more
    less

10
投票

我根据 Florian 的答案编写了一个小脚本,使用 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 行,您可以编辑它们,当您保存并退出时,大文件中的这些行将自动被您保存的行覆盖。


3
投票

我遇到了同样的问题,但它是一个 300GB 的 mysql 转储,我想摆脱

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

3
投票

对于巨大的单行(打印从

1
99
的字符):

cut -c 1-99 filename

1
投票

emacs 可以很好地处理 100 兆字节的文件,我已经在日志文件上使用它,没有遇到太多麻烦。

但一般来说,当我有某种分析任务时,我发现编写 Perl 脚本是更好的选择。


1
投票

已经很晚了,但如果您只想浏览文件而不对其进行编辑,

cat
也可以完成这项工作。

% cat filename | less

或者简单的:

% less filename

0
投票

旧线程。但尽管如此(双关语:))。

 $less filename

如果您不想编辑而只是环顾四周(检查巨大的日志文件就是这种情况),则 less 可以有效地工作。

像vi这样的作品搜索较少

最好的部分是,它在大多数发行版上默认可用。所以生产环境也不会有问题。


-15
投票

这已经很旧了,但是, 使用 nano、vim 或 gvim

© www.soinside.com 2019 - 2024. All rights reserved.