删除n行跳过1行脚本


10

我想创建一个基本的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正则表达式。(免责声明:我写下了这个答案。)
贾斯珀(Jasper

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

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

Answers:


19

很简单的方法:

  1. 移至要删除的第一行。
  2. 记录一个宏: qa3ddjq
  3. 重复多次:1000 @ a

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

请参阅:help recording


2
棒极了!!!非常感谢您,这对我
有用

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

3
另外,如果您不想1000@q在最后运行类似的内容,则可以创建一个递归宏:qa3ddj@aq@a,尽管您可能需要首先执行qaq以确保"a开始为空。
詹姆斯

17

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

:%norm j3dd

那是:

  • %:每行
  • norm:像在普通模式下一样运行以下键
  • j3dd:下线然后删除3行

因此,从第一行转到第二行,然后删除接下来的3行。第二个Text I want to keep.现在在第二行。向下一行,删除3.冲洗并重复。


注意:如果您不想处理整个文件,则可以将替换为%norm,例如5,$norm从第五行到文件末尾进行处理。


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

6

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

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

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

下一个命令是一个常规(:g)命令,该命令匹配以DELETE ME且以开头的所有行。

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


4

我知道这是vi频道,但是对我来说这是一个sed问题。

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

因此,您可以将其整理成一个vi解决方案:

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

1
sed解决方案为+1。
Christian Brabandt

3

另一种选择(我想我们从第1行开始,然后删除第2-4、6-8行,依此类推,以此类推)。

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

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

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


1

另一种选择:您想保留任何行: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)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.