我想创建一个基本的Vim脚本,该脚本仅删除n行,跳过1行并重复直到文档结束。我不在乎特定的匹配项,我只想删除该行。例如;
所以我想对整个文档重复命令3ddj

Text I want to keep.   
Text I want to delete.  
Text I want to delete.  
Text I want to delete.  
Text I want to keep.  
Text I want to delete.  
Text I want to delete.  
Text I want to delete.  
Text I want to keep.  
Text I want to delete.  
Text I want to delete.  
Text I want to delete.   


所以看起来......

Text I want to keep.  
Text I want to keep.  
Text I want to keep.  


谢谢。 />

评论

您在问题中包括了标签regular-expression,但该问题似乎并未指定使用正则表达式执行此操作的原因。如果您实际上正在寻找使用正则表达式的东西,那么可能会感兴趣stackoverflow.com/questions/17735289/…。这个问题是关于Notepad ++的,但是答案只用了pcre正则表达式。 (免责声明:我写了这个答案。)

下次您问一个问题时,无需编写“谢谢。很好的解决方案!”每个答案。当您尝试在答案上创建新评论时,甚至会写出来。

此外,在这里表示赞赏的正确方法是接受最适合您的答案,并认可您认为有用或有用的任何答案。人们宁愿看到它,也不愿说“谢谢”。

#1 楼

非常简单的方法:


移至要删除的第一行。
qa3ddjq

用高数字重复它: 1000 @ a

第三步将重复该宏一千次,直到遇到错误为止。
点击文件结尾(因此没有要删除的行)会产生错误,并且宏的重复被取消。

请参阅:help recording

评论


太棒了!!!非常感谢你,这对我有用:D

–马克斯·科普利
19-09-23在5:33

说明:q(在命令模式下,以及在vim或其他最新的替代版本[neovim等中,但在原始vi中却没有)表示“开始记录,并将其放入'下一个字母'缓冲区”。因此:qa表示“开始记录到'a'缓冲区”。然后记录此后键入的每个键(直到命令模式下的下一个q)(您甚至可以记录:进入编辑模式,键入内容,转义到命令模式等)。然后12 @ a将重复在缓冲区“ a”中记录的任何动作12次。

–奥利维尔·杜拉克(Olivier Dulac)
19-09-24在13:28



另外,如果您不想在末尾运行类似1000 @ q的内容,则可以创建一个递归宏:qa3ddj @ aq @ a,尽管您可能需要先执行qaq才能确保“ a开头为空。

–詹姆斯
19-09-24在15:14

#2 楼

对我来说,最简单的解决方案是:

:%norm j3dd


即:



%:每行

norm:就像在正常模式下一样运行以下键

j3dd:下线然后删除3行


所以从第一行,转到第二行,然后删除接下来的3行。第二个Text I want to keep.现在位于第二行。向下移动一行,删除3。漂洗并重复。行到文件末尾。

评论


很好的选择!在vim中工作(不是vi)。我以前从未听说过“规范”! (而且我有点像vi [m]怪胎)

–奥利维尔·杜拉克(Olivier Dulac)
19-09-24在13:33



#3 楼

您已经有了一些不错的解决方案。这是另一个:

:g/^/if line('.')%4!=1|:s/^/DELETE ME/|endif
:g/^DELETE ME/d


首先,我们在每行上执行一个操作(:g^匹配(行首)),并为每个行号执行linenumber % 4的结果。如果结果不等于1,则在行的开头添加DELETE ME,标记要由下一条命令删除的行。

下一条命令是常规(:g)命令,该命令与

注意,您不能使用第一个DELETE ME命令立即删除该行,因为这会改变结果的模数计算,因此,我们必须首先标记行,然后在第二步中将其删除。

#4 楼

我知道这是vi通道,但是对我来说这是sed问题。

sed -ne 'p;n;n;n' <file >newfile


所以您可以将其纠缠为vi解决方案:

:0
!Gsed -ne 'p;n;n;n'


评论


sed解决方案为+1。

–克里斯蒂安·布拉班特(Christian Brabandt)
19-09-24在6:37

#5 楼

另一种选择(我想我们从第1行开始,并删除第2-4、6-8行,依此类推,以此类推),如下所示:

while line(".") < line("$")
    silent +1delete _ 3
endwhile


如果希望以交互方式执行此操作,则可以使用“命令行寄存器”。也就是说,先按

:+1del 3<CR>,然后按1000@:

#6 楼

另一种选择:您希望保留任何行:1、4等。
您可以使用:

awk '!((FNR-1)%3)'  file > newfile
      # awk: when a condition is given without action:
      #        prints the lines for which the condition returns 0.
      # FNR designates the line number in the current file.
      # a%3 : takes the modulus of a and 3. ( 0%3=0, 1%3=1, 2%3=2, 3%3=0, 4%3=1, etc.) 
      # This will be 0 for 3, 6, etc. 
      # But we want it to be 0 (true) for 1, 4, etc : so we substract 1 to NR

# to see that it keeps those lines:
seq 1 20 | awk '!((NR-1)%3)'
1
4
7
10
13
16
19


另一种选择:如果您知道这些行,要匹配一些独特的样式:

# for exemple each line you want contains "some pattern":
fgrep "some pattern" file > newfile
# (or regular grep if you want "some pattern" to be interpreted as a regexp)