Regex Vim:正则表达式,用于删除除以给定数字列表开头的行以外的所有行
我有一个csv文件,其中除第一行外的每一行都以数字开头,如下所示:Regex Vim:正则表达式,用于删除除以给定数字列表开头的行以外的所有行,regex,vim,regex-negation,Regex,Vim,Regex Negation,我有一个csv文件,其中除第一行外的每一行都以数字开头,如下所示: subject,parameter1,parameter2,parameter3 1,blah,blah,blah 3,blah,blah,blah 2,blah,blah,blah 44,blah,blah,blah 12,blah,blah,blah 14,blah,blah,blah 11,blah,blah,blah 10,blah,blah,blah 11,blah,blah,blah 13,blah,blah,bla
subject,parameter1,parameter2,parameter3
1,blah,blah,blah
3,blah,blah,blah
2,blah,blah,blah
44,blah,blah,blah
12,blah,blah,blah
14,blah,blah,blah
11,blah,blah,blah
10,blah,blah,blah
11,blah,blah,blah
13,blah,blah,blah
3,blah,blah,blah
...
:g!/^[1 6 12]\|^subject/d
我想删除除第一行以外的所有行,比如说,以数字1、6、12开头的行。
我试着这样做:
subject,parameter1,parameter2,parameter3
1,blah,blah,blah
3,blah,blah,blah
2,blah,blah,blah
44,blah,blah,blah
12,blah,blah,blah
14,blah,blah,blah
11,blah,blah,blah
10,blah,blah,blah
11,blah,blah,blah
13,blah,blah,blah
3,blah,blah,blah
...
:g!/^[1 6 12]\|^subject/d
但12被解释为“1或2”,因此这也会删除以2开头的行
我遗漏了什么,最有效的方法应该是什么?
顺便说一句,我的列表不是1、6、12,而是包含多个单位数和两位数的数字。使用全局匹配:
:v/^\(subject\|1\|6\|12\),/ delete
对于与该正则表达式不匹配的每一行,将其删除
它产生:
subject,parameter1,parameter2,parameter3
1,blah,blah,blah
12,blah,blah,blah
编辑:刚才我意识到您已经在使用全局匹配。您的错误在角色类中。它匹配其中的任何字符,而不考虑重复的字符,例如数字1、2、6和空格。您必须像我以前做的那样,在不同的分支中将它们分开。使用全局匹配:
:v/^\(subject\|1\|6\|12\),/ delete
对于与该正则表达式不匹配的每一行,将其删除
它产生:
subject,parameter1,parameter2,parameter3
1,blah,blah,blah
12,blah,blah,blah
编辑:刚才我意识到您已经在使用全局匹配。您的错误在角色类中。它匹配其中的任何字符,而不考虑重复的字符,例如数字1、2、6和空格。您必须像我以前做的那样,在不同的分支中将它们分开。一个“功能性”替代方案:
:g/./if index([1,12,6],str2nr(split(getline("."),",")[0]))<0|exec 'normal! dd'|endif
:g//if索引([1,12,6],str2nr(拆分(getline(“.”,“,”[0]))a“功能”替代方案:
:g/./if index([1,12,6],str2nr(split(getline("."),",")[0]))<0|exec 'normal! dd'|endif
:g//if索引([1,12,6],str2nr(split(getline(“.”,“,”[0]))字符类[1 6 12]
表示“该类中的任何单个字符,
i、 e.”、1、2、6
中的任何一个(重复的1
被忽略)
你可以用
:g!/^1,\|^6,\|^12,\|^subject/d
这与您的原始语法非常接近,但它可以工作(在Mac OS X上使用vim进行测试)
注意-必须包含逗号,以便以1开头的行不会“保护”11
、12345
等
不过,您可能希望使用grep
以不同的方式执行此操作
将所有“白名单”编号放在一个文件中,每行一个,如下所示:
^subject
^1,
^2,
^6,
^12,
那就做吧
grep -f whitelist csvFile
输出将是您的“编辑”文件(您可以通过管道将其传输到新文件)
如果你对“效率”更感兴趣,你可以让你的文本文件(我们继续称它为白名单
)仅仅
并使用以下命令:
cat whitelist | xargs -I {} grep "^"{}"," cvsFile
这需要解释一下
xargs - take the input one line at a time
-I {} - and insert that line in the command that follows, at the {}
这意味着grep命令将运行n
次(在白名单文件中每行运行一次),并且每次馈入grep
的正则表达式都是
"^" - start of line
{} - contents of one line of the input file (whitelist)
"," - comma that follows the number
这是一种简洁的写作方式
grep "^subject," csvFile; grep "^1," csvFile; grep "^2," csvFile;
等等
它的优点是,您现在可以按任何方式生成白名单-只要它最终出现在一个文件中,一次一行,您就可以使用它;缺点是您实际上正在运行grep n次。如果您的文件变得非常大,并且白名单中有大量项目,这可能会开始成为一个问题;但是您的操作系统可能会在第一次读取后将文件放入缓存,速度非常快。使用^
锚定使正则表达式非常高效-一旦找不到匹配项,它就会转到下一行。字符类[1 6 12]
表示“该类中的任何单个字符,
i、 e.”、1、2、6
中的任何一个(重复的1
被忽略)
你可以用
:g!/^1,\|^6,\|^12,\|^subject/d
这与您的原始语法非常接近,但它可以工作(在Mac OS X上使用vim进行测试)
注意-必须包含逗号,以便以1开头的行不会“保护”11
、12345
等
不过,您可能希望使用grep
以不同的方式执行此操作
将所有“白名单”编号放在一个文件中,每行一个,如下所示:
^subject
^1,
^2,
^6,
^12,
那就做吧
grep -f whitelist csvFile
输出将是您的“编辑”文件(您可以通过管道将其传输到新文件)
如果你对“效率”更感兴趣,你可以让你的文本文件(我们继续称它为白名单
)仅仅
并使用以下命令:
cat whitelist | xargs -I {} grep "^"{}"," cvsFile
这需要解释一下
xargs - take the input one line at a time
-I {} - and insert that line in the command that follows, at the {}
这意味着grep命令将运行n
次(在白名单文件中每行运行一次),并且每次馈入grep
的正则表达式都是
"^" - start of line
{} - contents of one line of the input file (whitelist)
"," - comma that follows the number
这是一种简洁的写作方式
grep "^subject," csvFile; grep "^1," csvFile; grep "^2," csvFile;
等等
它的优点是,你现在可以以任何方式生成你的白名单——只要它最终出现在一个文件中,一次一行,你就可以使用它;缺点是您实际上正在运行grep n次。如果您的文件变得非常大,并且您的白名单中有大量项目,这可能会开始成为一个问题;但由于您的操作系统可能会在第一次读取后将文件放入缓存,因此速度非常快。使用^
锚定使正则表达式非常高效-一旦找不到匹配项,它就会转到下一行。顺便说一句,:v
是:g!的同义词
.BTW,:v
是:g代码>。希望我能投票支持grep技巧,但我的票数不够reputation@geo909-我很乐意接受你的赞扬,而不是一票!我希望我能投格雷普的一票,但是票数不够reputation@geo909-我很乐意接受你的赞扬,而不是一票!