请考虑以下数据:
Class Gender Condition Tenis
A Male Fail Fail 33
A Female Fail NotFail 23
S Male Yellow 14
BC Male Happy Elephant 44
Run Code Online (Sandbox Code Playgroud)
我有一个逗号分隔值与未格式化的列表(它在标签和空格之间变化).
在一个特定的专栏中,我有复合词,我想消除空间.在上面的例子中,我想用"Fail_"替换"Fail",用"Happy_"替换"Happy".
结果如下:
Class Gender Condition Tenis
A Male Fail_Fail 33
A Female Fail_NotFail 23
S Male Yellow 14
BC Male Happy_Elephant 44
Run Code Online (Sandbox Code Playgroud)
我已经设法分两步完成:
:%s/Fail /Fail_/g
:%s/Happy /Happy_/g
Run Code Online (Sandbox Code Playgroud)
问题:由于我对gVim很新,我试图一起实现这些替换,但我找不到如何做到这一点*.
完成此步骤后,我将使用以下内容将数据制成表格:
:%s/\s\+/,/g
Run Code Online (Sandbox Code Playgroud)
并获得最终结果:
Number,Gender,Condition,Tenis
A,Male,Fail_Fail,33
A,Female,Fail_NotFail,23
S,Male,Yellow,14
BC,Male,Happy_Elephant,44
Run Code Online (Sandbox Code Playgroud)
在SO,我搜索[vim] :%s two is:question和一些变化,但我找不到相关的线程,所以我想我缺乏正确的术语.
编辑:这是实际数据(超过100万行).问题从第12列开始(例如"失败种植"应为"Fail_Planting").
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
Run Code Online (Sandbox Code Playgroud)
您可以在替换的右侧使用表达式.
:%s/\(Fail\|Happy\) \|\s\+/\= submatch(0) =~# '^\s\+$' ? ',' : submatch(1).'_'/g
Run Code Online (Sandbox Code Playgroud)
所以这找到Fail或者是Happy空格,然后转换检查以查看匹配的部分是否完全是空白.如果它不使用捕获的部分并附加下划线,则用逗号替换它.submatch(0)是整个比赛,submatch(1)是第一个捕获组.
看看:h sub-replace-expression.如果你想做一些非常复杂的定义,你可以定义一个函数.
非常神奇的版本
:%s/\v(Fail|Happy) |\s+/\= submatch(0) =~# '^\v\s+$' ? ',' : submatch(1).'_'/g
Run Code Online (Sandbox Code Playgroud)
您拥有将它们组合在一起所需的所有部件|.例:
:%s/\>\s\</_/g|%s/\s\+/,/g
Run Code Online (Sandbox Code Playgroud)
我正在使用\>并\<找到它们之间只有一个空格的单词,以便我们可以替换它_.
有关更多帮助请参阅:
:h /\>
:h :range
:h :bar
Run Code Online (Sandbox Code Playgroud)
如果某些条件是真的(或者写一个vimscript,但我的vimscript非常生疏),你也许可以尝试一个宏.我将展示您可以使用的示例宏:
t录音寄存器(我用t代表"temp")现在您已将宏存储在寄存器中,t您可以在文件的每一行上运行宏.如果文件中有100行,那么您已经完成了1并且有一个标题,因此您可以键入以下内容以在剩余的98行上运行它: