Regex VI-如何替换第6个逗号和第9个逗号之间的文本
在VIM中,如何使用regexp或其他技巧删除以下文本的多行中第6个逗号和第9个逗号之间的句点 更改自:Regex VI-如何替换第6个逗号和第9个逗号之间的文本,regex,vim,Regex,Vim,在VIM中,如何使用regexp或其他技巧删除以下文本的多行中第6个逗号和第9个逗号之间的句点 更改自: 4,阿富汗,2,中等,19511951.54134.7563705.3957840.151,12.009 4,阿富汗,5,恒定生育率,20232023.521628.6720554.28242182.952,64.613 致: 4,阿富汗,2,中等,19511951.5,413475637053957840151,12.009 4,阿富汗,5,恒定生育率,20232023.521628672
4,阿富汗,2,中等,19511951.5
4134.7563705.3957840.151,12.009
4,阿富汗,5,恒定生育率,20232023.5
21628.6720554.28242182.952,64.613
致:4,阿富汗,2,中等,19511951.5
,413475637053957840151,12.009
4,阿富汗,5,恒定生育率,20232023.5
21628672055428242182952,64.613
我有一个csv文件,里面有很多类似的记录。
由于第6和第9个逗号的位置可能不在同一列中,
我无法使用分块视觉模式删除这些句点
一种方法是在excel中将逗号拆分为列,并在excel的列中替换它。但是我的csv文件超过了100兆字节,而且我的计算机速度太慢,无法完成
根据我的vi和regexp知识,我可以使用下面的regexp来定位第6个逗号的位置,但这还不够。/\([^,]*,\)\{-6}
在多行csv文件中,是否有任何高级regexp用于删除第6个逗号和第9个逗号之间的句点?可视选择并使用
:s/\%V\.//g
在选择上按照注释中的建议,您可以使用如下简单的awk:
awk'BEGIN{FS=OFS=“,”}{for(i=7;i这里我们使用纯Vim解决方案:
:%normal 6f,v3f,:s/\%V.\+\%V/\=substitute(submatch(0),'\.','','g')/
:[range]normal
在[range]
覆盖的每一行上执行正常模式命令
。请参阅:帮助:normal
%
是一个覆盖整个缓冲区的范围,因此命令将在每一行执行。如果需要不同,请参阅:help:range
6f,
将光标移动到当前行的第6个,
。请参阅:help f
v3f,
启动视觉选择,该选择延伸到第三个,
右侧,有效覆盖从第六个,
到第九个,
的文本
:s/
将当前行中第一次出现的
替换为
。请参见:h:s
\%V.\+\%V
是我们的模式。开头和结尾的\%V
将搜索限制到最后一个可视选择,而\+
仅表示“任何字符中的一个或多个”,因此我们的替换仅适用于从第6个,
到第9个,
的文本。请参见:help\%V
和:help\+
- 命令的
部分以\=
开头,这是一个特殊项,允许我们将
的输出用作替换。请参见:help sub replace expression
- 我们的表达式是
submatch(0),'\.','','g')
,它在父替换(submatch(0)
)的整个匹配中(\.
)替换每个('g'
)文本(\.
),有效地删除它们。请参见:help submatch()
和:help submatch()
对不起,对于不清楚的描述,我已经更新了我的问题和我所尝试的。你会考虑一个更好的工具,比如<代码> AWK<代码>吗?<代码>生育率<代码>出现在第二记录的一个新行中吗?是的,而且CSV文件中还有很多其他长度可变的行,唯一的区别是逗号,非常很抱歉误解,很抱歉描述不清楚,因为在多行文件中,第6和第9个逗号的位置可能不在同一列中,我无法使用分块视觉模式删除这些句点。非常感谢您提供了简洁的解决方案!还有两个问题,首先,此解决方案中使用的数字
1
是什么?我只想知道我已经了解了一些awk的基本知识,但是我很难找到1
的用法。其次,如何用awk将更改写回csv文件?1
(或任何非零数字)是一个在awk中打印所有记录的简捷条件+操作。要内联保存更改,请使用awk-i inplace'BEGIN{FS=OFS=“,”}{for(i=7;i_tmp&&mv_tmp file.csv
可以工作是的,带有输出重定向器>的第二个解决方案可以工作,我的awk是呆滞的,所以我正在尝试“awk-i”解决方案非常感谢分享功能强大的vi解决方案。首先,只需一些注释,f6、
和vf3、
应更改为6f、
和v3f、
,因为f6、
可能首先匹配文字6
,而不是。其次,当我运行此命令时:normal f6、vf3、\+%V/\=替换(子匹配(0),'\.','','','g')/
对于单行文本,它不起作用。但如果我将其拆分为以下两个命令,它就会起作用::普通f6,vf3,//单击enter
:s/\%V.\+\%V/\=替换(子匹配(0),'\.,'','','g'))///单击enter
你知道原因吗?以下命令适用于单行替换::exe::普通6f,v3f,'.\124;:s/\%V.\+\%V/\=submatch(0),'\.','','','g')/
,但我无法将其应用于范围符号为%Oh good…我从哪里提取这些f6,
和vf3,
?