2012-08-01 93 views
2

我对Vim一点都不熟悉,但是我正在处理大文本文件(〜1G),而我的标准文本编辑器并没有切割它。如何在Vim中追加每一行?

我的文件目前这种格式:

Arbitrary_title_of_sequenceA 
SEQ1SEQ1SEQ1SEQ1 
SEQ2SEQ2SEQ2SEQ2 
Arbitrary_title_of_sequenceB 
SEQ1SEQ1SEQ1SEQ1 
SEQ2SEQ2SEQ2SEQ2 

我需要追加“SEQ2”行的“SEQ1”行像这样的一种便捷方式:考虑到大小

Arbitrary_title_of_sequenceA 
SEQ1SEQ1SEQ1SEQ1SEQ2SEQ2SEQ2SEQ2 
Arbitrary_title_of_sequenceB 
SEQ1SEQ1SEQ1SEQ1SEQ2SEQ2SEQ2SEQ2 

这些文件中,单独执行每行不是真正的选择。任何帮助将非常感激!

回答

1
:1,$s/\(.*\n\)\(.*\)\n\(.*\n\)/\1\2\3/ 

1,$   -> range is all file 
s/PAT1/PAT2/ -> substitute PAT1 with PAT2 
.*   -> match any character except new line 
\n   -> match new line 
\(PAT1\)  -> capture/remember the string that matched PAT1 
\1,\2,\3  -> refers to the captured string for captures in order 

也在使用的sed的而不是vim应该更快:

sed -i 'n;N;s/\n/ /' input_file 

这可以概括为:

Read a line 
Read another line and print previous line (n) 
Read another line and append it to the previous line (N) 
find the first newline and change it to space (s/\n/ /) 
print the line (or merged lines) 
+0

不应该使用sed命令:'sed -i'n; N; s/\ n //'input_file'。请注意's/\ n //',所以不要在新加入的行之间留出空格。 – 2012-08-01 21:47:32

2

有关提供正确的样本开始与什么?

:g/SEQ1/norm Jx 

做什么我想你想

  • :g/SEQ1:global命令,它允许您作用于含有所述图案SEQ1每一行。见:help :global
  • norm是您用于执行正常模式命令的:normal命令,这里是每个与:g/SEQ1匹配的行。请参阅:help :normal

之后在问题来正常命令:

  • J用于连接与下面的行中的当前行。
  • x用于删除Vim自动添加的<Space>
+3

Vim高尔夫时间:':g/SEQ1/j!'。 ':j'是':join'的缩写,它是用于连接行的ex命令。 '!'表示':join'不会插入或删除任何空格。请参阅':h:j'获得更多帮助 – 2012-08-01 21:37:49

+2

根据三种线中哪一种更容易与模式相匹配,除了':g/SEQ1/j!'也考虑':g/SEQ2/-j!'和':g/title/+ j!'。请注意,与替换或普通模式命令相比,这三个命令的效率最高。 – 2012-08-02 04:08:08

+0

你们摇滚。我的初步答案实际上是基于匹配'SEQ2',但我认为匹配'SEQ1'更有效。 – romainl 2012-08-02 06:19:35

0

我觉得romainl的解决方案是,如果你有一个可靠的“SEQ1”模式,你可以抓住到最佳。如果没有,你想从字面上加入每隔二行,你可以很容易地与宏做到这一点:

qqjJxjq 

点击G,看看有多少行是在文件中重复刚才的宏多次(它不无论它高于你的需要)。所以如果文件是1000行,你可以做[email protected]。这种解决方案很容易记住并集成到您的正常工作流程中。