2010-03-04 102 views
8

如何替换大文件(> 100MB)中的所有换行符? 我试图做如何替换VIM中的换行符

:%s/\n/, /g

但它的速度太慢。

+0

你为什么想在VIM中做到这一点。你只会得到一条你无法阅读的长线(用眼睛看)。另外,还有什么线结局存在:DOS,UNIX,MAC还是组合? – Marichyasana 2013-01-01 23:06:17

回答

8

所以,我经历了和测试/定时一些被其他人给的答案之前整合,加上我自己的python答案。以下是我的了:

TR:

> time tr "\n" "," <lines> line 
real 0m1.617s 
user 0m0.100s 
sys  0m1.520s 

蟒蛇:

> time python -c 'import sys; print sys.stdin.read().replace("\n",", "),' <lines> line 
real 0m1.663s 
user 0m0.060s 
sys  0m1.610s 

AWK:

> time awk '{printf("%s, ", $0)}' lines > line         
real 0m1.998s 
user 0m0.390s 
sys  0m1.600s 

点的Perl:

> time perl -e 'while (<>) { chomp; print "$_, " }' lines > line 
real 0m2.100s 
user 0m0.590s 
sys  0m1.510s 

的sed:

> time sed 's/$/, /g' lines > line            
real 0m6.673s 
user 0m5.050s 
sys  0m1.630s 

这里是我使用的文件:

> ls -lh lines 
-rw-r--r-- 1 some one 101M 2010-03-04 19:54 lines 
> wc -l < lines 
1300000 
> head -n 3 < lines 
The pretty pink puma pounced on the unsuspecting aardvark, the scientist watched. 
The pretty pink puma pounced on the unsuspecting aardvark, the scientist watched. 
The pretty pink puma pounced on the unsuspecting aardvark, the scientist watched. 
> head -n 1 < lines | wc -c 
82 

最初采取了Cygwin的时序,他们现在已经采取完全更新的Ubuntu 9.10。此外,文本文件的大小增加到100兆,线宽为80个字符。正如你可以看到除sed以外的其他任何东西都是一个好主意。

+2

之前测试它,我非常怀疑你的awk结果。你几次命令,而不只是一次。 Python不应该比awk快,考虑到导入模块和东西需要时间 – ghostdog74 2010-03-05 00:56:35

+0

它运行了几次,大概是平均值。只要再跑10次,每次1.7XX。如果我不使用cygwin awk,可能会有所不同。 – 2010-03-05 01:01:01

+0

@ ghostdog74 你对我的awk结果怀疑是正确的,我重新在真正的Linux机器上运行它,并且速度更快。 – 2010-03-05 02:46:27

2

使用此Perl脚本浏览您的文件;它将比使用VIM在内存中保存所有内容更快。只需将输出输出到新文件。

#!/usr/local/bin/perl 

while (<>) { 
    $_ =~ s/\n/,/g; 
    print $_; 
} 
+0

我猜测perl解释器不够聪明,知道在这种情况下'$ _'除了最后一个字符之外不能有换行符 - 'chomp'可能要快很多。 – Cascabel 2010-03-04 14:43:56

+0

@Jefromi 在我完全不科学的测试中,在100 meg文件上使用chomp速度约为300ms。 – 2010-03-05 03:08:51

0

你必须在vim中做到这一点吗?

有很好的Unix实用程序可以进行基于字符的翻译。它叫做tr。 一些reference

你的情况,那就是:

 
tr "\n" "," < input_file > output_file 
+0

这几乎肯定比我发布的解决方案更快,但不幸的是,它会根据OP的要求替换“,”而不是“,”。我不确定有什么方法可以用'tr'来做,是吗? – Cascabel 2010-03-04 14:47:36

+0

tr只需要单个字符 – ghostdog74 2010-03-04 15:07:17

+0

不,没有,我没有注意到那里的空间。要放置超过1个字符,可以使用sed作为下面发布的人。 – pajton 2010-03-04 15:31:37

3

:%s/$/, /后跟一个:1,$j可能会更快。否则,请在外部工具中执行此操作:

perl -e 'while (<>) { chomp; print "$_, " }' input_file > output_file 

awk '{printf("%s, ", $0)}' input_file > output_file 

不知道脱离我的头,这将是最快的。

+0

'perl -ne'chomp;打印“$ _”,“文件”。 '-n'“假设while循环” – ghostdog74 2010-03-04 15:08:17

+0

良好的调用'-n'。 – Cascabel 2010-03-04 15:20:45

+0

@sparrkey,“perl将运行得更快”是不合理的。 – ghostdog74 2010-03-05 01:20:48

0
$ more file 
aaaa 
bbbb 
cccc 
dddd 
eeee 

$ awk 'NR>1{printf("%s, ", p)}{p=$0}END{print p}' file 
aaaa, bbbb, cccc, dddd, eeee 

$ sed -e :b -e '$!N;s/\n/, /;tb' file 
+0

你测试过你的sed命令吗? sed'N; s/\ n /,/'文件 – sparkkkey 2010-03-05 16:21:49

+0

不是。它削减了维基的粘贴,但我猜维基有时候不可信。 – ghostdog74 2010-03-05 23:58:07

0

最好的工具是sed,你可以使用它:!命令

所以使用:!sed -e 's/\n/,/g' % > %.tmp ; cat %.tmp > % ; rm %.tmp'

你需要创建一个变化的tmp文件在当前文件

+0

你测试了你的sed命令吗? – ghostdog74 2010-03-05 01:05:34

+0

是的,我在 – shingara 2010-03-05 07:52:24