【问题标题】:Vim: How to delete the same block of text over the whole fileVim:如何在整个文件中删除相同的文本块
【发布时间】:2014-04-18 15:12:40
【问题描述】:

我正在查看一些包含 Java 异常垃圾邮件的日志。垃圾邮件越来越多,很难看到其他错误。

在 vim 中可以使用可视模式选择文本块。删除该块在文件中出现的每个位置。

如果 vim 做不到,我知道一个愚蠢的问题,vim 可以做任何事情。还有哪些其他 Unix 工具可以做到这一点?

【问题讨论】:

  • 你是什么意思的“块”?如果它是一行中的一串连续字符,那么您在下面已经有了几个答案。如果你的意思是你可以在可视块模式下选择的那种东西,跨越不止一行,那么它就更复杂了。
  • 感谢下面的答案和这个问题,stackoverflow.com/questions/101258/…,我想出了如何去做。 Benji,堆栈跟踪可以是 1 到 N 行,带有各种空格,通常是制表符。 1. 视觉选择堆栈的顶行 2. 拖动到缓冲区 a 3. 视觉选择堆栈的底部行 4. 拖动到缓冲区 b 5. g:/R>a/,/R>b/d 由于空格、换行符,对整个文本块进行拉拽对我不起作用。拉入搜索命令的模式与文件文本不匹配。有没有简化?

标签: vim editor vi


【解决方案1】:

听起来您正在寻找:global 命令

:g/pattern/d

:global 命令采用:g/{pat}/{cmd} 的形式。读作:运行命令,{cmd},在每行匹配模式上,{pat}

您甚至可以为:delete(简称:d)命令提供范围。例子:

:,+3d
:,/end_pattern/d

把这个和:global 命令放在一起,你可以完成一大堆。例如:g/pat/,/end_pat/d

如需更多帮助,请参阅:

:h :g
:h :d
:h :range

【讨论】:

  • 投反对票,因为这些方法不符合 OP 要求的帮助。
  • @MikeDiehn 您意识到 OP 接受了这个答案,对吧?我鼓励你特别回顾stackoverflow.com/help/privileges/vote-down“每当你遇到一个非常草率、不费吹灰之力的帖子,或者一个明显不正确且可能有危险的答案时,请使用你的反对票。”和“否决权应保留在极端情况下。它不能代替沟通和编辑。”
  • 嗨,尼基塔!我很抱歉!我没有阅读过该指南,至少最近在我在这里投反对票时还没有意识到它!非常感谢您提醒我注意我的错误。如果我可以取消邀请,我会的。
【解决方案2】:

Vim

删除所有匹配的行:

:g/regex/d

仅删除匹配项本身:

:%s/regex//g

在任何一种情况下,您都可以将可视选择复制到命令行,方法是拉出它,然后使用<C-r>" 将其插入。例如,如果您的光标 (|) 定位如下:

hello wo|rld

然后你可以用viw选择world,用y拉出选择,然后:g/<C-r>"/d

sed

删除所有匹配的行:

$ sed '/regex/d' file

仅删除匹配项本身:

$ sed 's/regex//g' file

grep

删除所有匹配的行:

$ grep -v 'regex' file

grep 仅按行操作,因此不能只删除行内的匹配项。

【讨论】:

  • 很抱歉投了反对票,我没有阅读关于何时使用它们的说明,也没有意识到它们有多么激烈!如果可以的话,我会撤消它。
【解决方案3】:

你可以在 vim 中试试这个

:g/yourText/ d

【讨论】:

  • 很抱歉投了反对票,我没有阅读关于何时使用它们的说明,也没有意识到它们有多么激烈!如果可以,我会撤消它。
【解决方案4】:

根据我们在 cmets 中的讨论,我猜一个“块”意味着几行完整的行。如果第一行和最后一行不同,那么您在 cmets 中提供的方法应该可以工作。 (“独特”是指这些行不会出现在您的日志文件中的其他任何地方。)

为了简化,我将使用"ay$ 将第一行拉入寄存器a"by$ 将最后一行拉入寄存器b,而不是使用可视模式。 (我打算建议 "ayy"byy,但这会捕获换行符)

为了安全起见,我会锚定模式:/^{text}$/,以防日志文件包含类似“注意 {text} 标记 Java 异常的开始”之类的行。在命令行中,我会按照您的建议使用<C-R>a<C-R>b 粘贴两个寄存器的内容。

:g/^<C-R>a$/,/^<C-R>b$/d

如果抽出的文本包含对搜索模式具有特殊含义的字符怎么办?为了真正安全起见,我会使用\V(非常非魔法)修饰符并转义任何斜杠和反斜杠:

:g/\V\^<C-R>=escape(@a, '/\')<CR>\$/,/\V\^<C-R>=escape(@b, '/\')<CR>\$/d

请注意,&lt;C-R&gt;= 会将您置于新的命令行,然后您会使用 &lt;CR&gt; 返回主命令行。

在编写 matchit 时 \V 不可用,这太糟糕了。它必须以搜索模式处理来自缓冲区的文本,就像这样。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-04-04
    • 2012-01-18
    • 1970-01-01
    • 2018-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-03
    相关资源
    最近更新 更多