用gVim替换所有文本组

时间:2014-09-24 19:14:53

标签: regex vim

考虑以下数据:

Class   Gender  Condition   Tenis
A   Male    Fail Fail   33
A   Female  Fail NotFail    23
S  Male     Yellow     14
BC  Male    Happy Elephant  44

我有一个逗号分隔的值与未格式化的列表(它在标签和空格之间变化)。

在一个特定的专栏中,我有复合词,我想消除空间。在上面的例子中,我想替换"失败"用"失败_"和#34;快乐"用"快乐_"。

结果如下:

Class   Gender  Condition   Tenis
A   Male    Fail_Fail   33
A   Female  Fail_NotFail    23
S  Male     Yellow     14
BC  Male    Happy_Elephant  44

我已经设法分两步完成:

:%s/Fail /Fail_/g
:%s/Happy /Happy_/g

问题:由于我对gVim很陌生,我试图一起实现这些替换,但我找不到如何做到这一点*。

完成此步骤后,我将使用以下内容将数据制成表格:

:%s/\s\+/,/g

得到最终结果:

Number,Gender,Condition,Tenis
A,Male,Fail_Fail,33
A,Female,Fail_NotFail,23
S,Male,Yellow,14
BC,Male,Happy_Elephant,44

在SO上,我搜索了[vim] :%s two is:question和一些变体,但我找不到相关的帖子,所以我想我缺少正确的术语。


编辑:这是实际数据(超过100万行)。问题始于第12栏(例如"失败种植"应该是"失败_Pinging")。

SP1     51F001      3   1   1   2   3   2001    52  52  H   Normal          17,20000076 23,39999962 NULL    NULL
SP1     51F001      3   1   1   2   3   2001    53  53  F   Fail Planting   0   0   NULL    NULL
SP1     51F001      3   1   1   2   3   2001    54  54  N   Normal          13,89999962 0   NULL    NULL

4 个答案:

答案 0 :(得分:7)

您可以在替换的右侧使用表达式。

:%s/\(Fail\|Happy\) \|\s\+/\= submatch(0) =~# '^\s\+$' ? ',' : submatch(1).'_'/g

因此,这会找到FailHappy或空格,然后转换检查以查看匹配的部分是否完全是空白。如果它不使用捕获的部分并附加下划线,则用逗号替换它。 submatch(0)是整个匹配,submatch(1)是第一个捕获组。

看看:h sub-replace-expression。如果你想做一些非常复杂的定义,你可以定义一个函数。


非常神奇的版本

:%s/\v(Fail|Happy) |\s+/\= submatch(0) =~# '^\v\s+$' ? ',' : submatch(1).'_'/g

答案 1 :(得分:6)

您拥有所需的所有部分,可以将它们与|组合在一起。例如:

:%s/\>\s\</_/g|%s/\s\+/,/g

我正在使用\>\<来查找只有一个空格的单词,以便我们可以将其替换为_

如需更多帮助,请参阅:

:h /\>
:h :range
:h :bar

答案 2 :(得分:5)

如果某些条件是真的(或者写一个vimscript,但我的vimscript非常生疏),你也许可以尝试一个宏。我将展示您可以使用的示例宏:

  • 在标题
  • 之后转到文件中的第一行
  • q 开始录制宏
  • t 选择要录制的注册t(我使用t代表&#34; temp&#34;)
  • ^ 移至行首
  • 2 w 移至第三个单词(向右移动2个单词)
  • e 移至单词
  • 的末尾
  • l (字母l)向右移动一个字符(到空格)
  • r 进入替换单字符模式
  • _ 输入下划线
  • j 向下移动一行
  • q 停止录制宏

现在您已将宏存储在寄存器t中,您可以在文件的每一行上运行宏。如果文件中有100行,那么您已经完成了1并且有一个标题,因此您可以键入以下内容以在剩余的98行上运行它:

  • 9 8 @

答案 3 :(得分:2)

这两个命令:

:%s/\(\a\) \(\a\)/\1_\2/g
:%s/\s\+/,/g

似乎适用于您的样本:

SP1,51F001,3,1,1,2,3,2001,52,52,H,Normal,17,20000076,23,39999962,NULL,NULL
SP1,51F001,3,1,1,2,3,2001,53,53,F,Fail_Planting,0,0,NULL,NULL
SP1,51F001,3,1,1,2,3,2001,54,54,N,Normal,13,89999962,0,NULL,NULL

但是这里有十进制数字,逗号作为分隔符会混淆&#34;逗号分隔的&#34;你的数据。事先将这些逗号更改为句点可能是一个好主意:

:%s/,/./g

SP1,51F001,3,1,1,2,3,2001,52,52,H,Normal,17.20000076,23.39999962,NULL,NULL
SP1,51F001,3,1,1,2,3,2001,53,53,F,Fail_Planting,0,0,NULL,NULL
SP1,51F001,3,1,1,2,3,2001,54,54,N,Normal,13.89999962,0,NULL,NULL