2013-04-22 49 views
2

我有一个数据文件如下。删除每行的第一个字符,并使用Vim追加

1,14.23,1.71,2.43,15.6,127,2.8,3.06,.28,2.29,5.64,1.04,3.92,1065 
1,13.2,1.78,2.14,11.2,100,2.65,2.76,.26,1.28,4.38,1.05,3.4,1050 
1,13.16,2.36,2.67,18.6,101,2.8,3.24,.3,2.81,5.68,1.03,3.17,1185 
1,14.37,1.95,2.5,16.8,113,3.85,3.49,.24,2.18,7.8,.86,3.45,1480 
1,13.24,2.59,2.87,21,118,2.8,2.69,.39,1.82,4.32,1.04,2.93,735 

使用vim,我想从每一行中取出1并将它们追加到最后。由此产生的文件将如下所示:

14.23,1.71,2.43,15.6,127,2.8,3.06,.28,2.29,5.64,1.04,3.92,1065,1 
13.2,1.78,2.14,11.2,100,2.65,2.76,.26,1.28,4.38,1.05,3.4,1050,1 
13.16,2.36,2.67,18.6,101,2.8,3.24,.3,2.81,5.68,1.03,3.17,1185,1 
14.37,1.95,2.5,16.8,113,3.85,3.49,.24,2.18,7.8,.86,3.45,1480,1 
13.24,2.59,2.87,21,118,2.8,2.69,.39,1.82,4.32,1.04,2.93,735,1 

我正在寻找一个优雅的方式来做到这一点。

其实我试过像

:%s/$/,/g 

然后

:%s/$/^./g 

但我不能使它工作。

编辑:呃,其实我在我的问题中犯了一个错误。在数据文件中,第一个字符是不总是1,他们是1,2和3的混合物所以,从这个问题,所有的答案,我想出了一个解决方案 -

:%s/^\([1-3]\),\(.*\)/\2,\1/g 

和它正在工作。

+3

':%s/^ 1,\(。* \)/ \ 1,1' – Kevin 2013-04-22 04:33:08

+1

替换s/$ /,/ g表示将行标记的末尾替换为0宽度,逗号。替换s /&/^./并没有什么意义:你要求用行首标记后面跟一个点来代替行尾标记。开始的行标记永远不会在行的末尾,所以vim决定你必须是一个文字'^'。 – 7stud 2013-04-22 04:46:04

+0

@ 7stud,感谢您的评论,它帮助。 – ramgorur 2013-04-22 05:19:24

回答

4

的正则表达式没有按”捕获不管您使用的是哪个号码,它的数字还是分隔符。也就是说,这样的工作对于有线路都1作为他们的第一号,或者114

:%s/\([0-9]*\)\(.\)\(.*\)/\3\2\1/ 

说明:

:%s//   - Substitute every line (%) 
\(<something>\) - Extract and store to \n 
[0-9]*   - A number 0 or more times 
.    - Every char, in this case, 
.*    - Every char 0 or more times 
\3\2\1   - Replace what is captured with \(\) 

所以:切碎1,<the rest>\1,分别为\2\3,并对它们进行重新排序。

+1

感谢您的解释。 – ramgorur 2013-04-22 04:54:26

+1

@ramgorur np。我的正则表达式可能不是最简单的,但如果你想移动多个不同的数字,它是最灵活的。 – timss 2013-04-22 04:57:46

1
:%s/^1,\(.*\)/\1,1/ 

这将在文件的每一行上进行替换。该\1取代一切由(.*)

+1

很确定你需要逃避在vim中捕获parens。 – Kevin 2013-04-22 04:34:14

+0

@凯文谢谢;编辑 – 2013-04-22 04:36:17

+0

如果您使用“非常神奇”(请参阅​​':help \ magic')选项,您不必越过捕捉parens(或一系列其他特殊字符,如{},|等)。尝试使用以\ \ v:为前缀的搜索:':%s/\ v^1(。*)/ \ 1,1 /'。注意:在非常神奇的模式下,如果你想匹配paren(或其他特殊字符),你必须逃避它。 – 2013-05-19 00:52:11

1
:%s/1,\(.*$\)/\1,1/gc 

.........................

4

:%s/^1,// 
:%s/$/,1/ 

可能会略有容易理解。

+0

这应该是正确的答案,因为这完全回答了问题。 – 2014-09-14 16:59:40

1

你也可以使用宏来解决这个问题。首先,考虑如何从行的开始删除1,并追加到末尾:

0 go the the start of the line 
df, delete everything to and including the first , 
A,<ESC> append a comma to the end of the line 
p paste the thing you deleted with df, 
x delete the trailing comma 

所以,总结起来,以下将转换一行:

0df,A,<ESC>px 

现在,如果你想这一套的修改适用于所有的线,你首先需要记录下来:

qj start recording into the 'j' register 
0df,A,<ESC>px convert a single line 
j go to the next line 
q stop recording 

最后,你可以执行你想使用宏观随时,或将您的整个文件转换为[email protected](如果您的行数超过99行,请使用高于99的数字)。

以下是完整版本:

qj0df,A,<ESC>[email protected] 

这其中可能会更容易比其他解决方案来掌握,如果你不使用正则表达式!

+0

如果你能解释命令会更有帮助。我之前从未在VIM中见过这样的符号。 – ramgorur 2013-04-24 05:09:54

+0

好的,我已经把命令分成了不同的子命令。我希望你会觉得它有用! – 2013-04-24 06:47:11

+0

这也很酷,谢谢。 – ramgorur 2013-04-24 07:40:10