geo*_*909 3 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,blah
3,blah,blah,blah
...
Run Code Online (Sandbox Code Playgroud)
我想删除除第一行以外的所有行,例如以数字 1,6,12 开头的行。我正在尝试这样的事情:
:g!/^[1 6 12]\|^subject/d
Run Code Online (Sandbox Code Playgroud)
但 12 被解释为“1 或 2”,因此这也会删除以 2 开头的行。
我缺少什么,最有效的方法应该是什么?顺便说一句,我的列表包含许多多个单位数和两位数,而不是 1、6、12。
字符类的[1 6 12]意思是“该类中的任何单个字符,
即其中的任何一个' ', 1, 2, 6(重复的1被忽略)。
你可以使用
:g!/^1,\|^6,\|^12,\|^subject/d
Run Code Online (Sandbox Code Playgroud)
这与您原来的语法很接近 - 但它有效(在 Mac OS X 上使用 vim 进行了测试)。
注意 - 包含逗号很重要,这样就line starting with 1不会“保护” 11,12345等。
不过,您可能想以不同的方式执行此操作 - 使用grep.
将所有“白名单”号码放入一个文件中,每行一个,如下所示:
^subject
^1,
^2,
^6,
^12,
Run Code Online (Sandbox Code Playgroud)
然后做
grep -f whitelist csvFile
Run Code Online (Sandbox Code Playgroud)
输出将是您的“编辑”文件(您可以通过管道将其传输到新文件)。
如果您对“效率”更感兴趣,您可以使您的文本文件(让我们继续称之为whitelist)
subject
1
2
6
12
Run Code Online (Sandbox Code Playgroud)
并使用以下命令:
cat whitelist | xargs -I {} grep "^"{}"," cvsFile
Run Code Online (Sandbox Code Playgroud)
这需要一些解释。
xargs - take the input one line at a time
-I {} - and insert that line in the command that follows, at the {}
Run Code Online (Sandbox Code Playgroud)
这意味着 grep 命令将运行n一次(白名单文件中的每行一次),并且每次输入的正则表达式grep将是以下内容的串联
"^" - start of line
{} - contents of one line of the input file (whitelist)
"," - comma that follows the number
Run Code Online (Sandbox Code Playgroud)
所以这是一种紧凑的写作方式
grep "^subject," csvFile; grep "^1," csvFile; grep "^2," csvFile;
Run Code Online (Sandbox Code Playgroud)
ETC。
它的优点是,您现在可以以任何您想要的方式生成白名单 - 只要它最终位于文件中,一次一行,您就可以使用它;缺点是你实际上运行了 n 次 grep 。如果您的文件变得非常大,并且白名单中有大量项目,这可能会成为一个问题;但由于您的操作系统可能会在第一次通读后将文件放入缓存中,因此速度确实相当快。锚点的使用^使正则表达式非常高效 - 一旦它找不到匹配项,它就会继续到下一行。