Emacs:反向搜索

9

有没有一种方法可以进行反向搜索? 我有一个非常大的日志文件,其中特定的模式填充了几十页。

20100414 alpha beta
20100414 alpha beta
<few dozen pages>
20100414 alpha beta
20100414 gamma delta
20100414 gamma delta
<few dozen pages>
20100414 gamma delta

问题是,我不知道“alpha beta”后面会跟什么文本。它可能是“gamma delta”或其他内容。因此,我想跳过所有包含“alpha beta”的行。


我是通过谷歌找到这个问题的。我的查询是“emacs搜索第一行不匹配”。我认为问题的文本很好,答案也很好。但我不确定问题的标题是否正确。我不是英语母语者(我是法国人),对我来说,“inverse search”意味着“向后搜索”。我是对的吗?问题的一个好标题是什么? - lrineau
6个回答

7

两个想法:

  1. M-x keep-lines <RET> REGEXP <RET>

    将删除不匹配正则表达式的所有行

  2. M-x grep <RET> grep -nH -e "<REGEXP>" -v <FILE>

    将找到不包含您的正则表达式的所有行。


5
FWIW,“flush-lines” 的作用与 “keep-lines” 相反,即删除匹配的行。 - Ivan Andrus

3

它类似于keep-lines和flush-lines,但它不修改缓冲区。 - slu

2

通常情况下,你无法进行逆向搜索,但是针对你的特定情况,你可以使用一个简单的函数:

(defun my-skip-lines-matching-regexp (regexp)
  "Skip lines matching a regexp."
  (interactive "sSkip lines matching regexp: ")
  (beginning-of-line)
  (while (and (not (eobp)) (looking-at regexp))
    (forward-line 1)))

然后在正则表达式中输入".+alpha beta"。

1

我通常通过使用正则表达式搜索来解决这个问题

C-u C-r ^20100414 [^a]

这个程序会搜索下一行是否为“20100414”,对于大多数情况来说这是可行的。它会找到“gamma delta”的那行,但是显然会错过那些看起来像“20100414 allegro”的行。

还有一个命令M-x flush-lines RE,可以删除所有与正则表达式RE匹配的行。这将修改缓冲区。


@RyanThompson 你可以使用'kbd'标签将文本包围起来,例如:<kbd>something</kbd>。 - Trey Jackson
这个搜索是如何排除我们想要搜索的大量行? - Nikana Reklawyks
@NikanaReklawyks 它搜索以“20100414”开头且后面不是“a”的第一行。由于他的数据如此结构化,这基本上找到了第一行不是“20100414 alpha beta”的行 - 显然它会跳过“20100414 apple”,因此根据您想要的详细程度,可以相应地自定义搜索字符串。 - Trey Jackson

0
一种常用的启发式方法是跳到文件末尾,然后向后搜索要跳过的文本。这种方法的成功显然取决于文件的内容,并且在所涉及的重复文本以单个块出现时效果最佳。

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接