我尝试在 Vim 中打开一个巨大的(~2 GB)文件,但它卡住了。我实际上不需要编辑文件,只需高效地跳转即可。
如何在 Vim 中处理非常大的文件?
我今天有一个 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.new
现在将是您编辑的文件,您可以删除原始的HUGEFILE
。这是多年来反复出现的问题。 (数字不断变化,但概念是相同的:如何查看或编辑大于内存的文件?)
显然
more
或 less
是仅仅读取文件的好方法 --- less
甚至提供 vi
之类的用于滚动和搜索的按键绑定。
对“大文件”进行Freshmeat搜索表明两个编辑器将特别适合您的需求。
一个是:lfhex ...一个大文件十六进制编辑器(取决于 Qt)。显然,这需要使用 GUI。
另一个似乎适合控制台使用:hed ...并且它声称有一个类似
vim
的界面(包括ex
模式?)。
我确信我见过其他 Linux/UNIX 编辑器能够对文件进行分页,而无需将其全部加载到内存中。然而,我不记得他们的名字。我将此回复作为“wiki”条目,以鼓励其他人将链接添加到此类编辑器。 (是的,我熟悉使用
split
和 cat
解决该问题的方法;但我正在考虑编辑器,尤其是控制台/curses 编辑器,它们可以免除这些问题并节省我们的时间/延迟和磁盘空间这种方法所带来的开销)。
我根据 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 行,您可以编辑它们,当您保存并退出时,大文件中的这些行将自动被您保存的行覆盖。
我遇到了同样的问题,但它是一个 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
对于巨大的单行(打印从
1
到 99
的字符):
cut -c 1-99 filename
emacs 可以很好地处理 100 兆字节的文件,我已经在日志文件上使用它,没有遇到太多麻烦。
但一般来说,当我有某种分析任务时,我发现编写 Perl 脚本是更好的选择。
已经很晚了,但如果您只想浏览文件而不对其进行编辑,
cat
也可以完成这项工作。
% cat filename | less
或者简单的:
% less filename
旧线程。但尽管如此(双关语:))。
$less filename
如果您不想编辑而只是环顾四周(检查巨大的日志文件就是这种情况),则 less 可以有效地工作。
像vi这样的作品搜索较少
最好的部分是,它在大多数发行版上默认可用。所以生产环境也不会有问题。
这已经很旧了,但是, 使用 nano、vim 或 gvim