1

I want to filter the text of an emacs buffer, a bit like you can filter text with grep.

Sounds simple, but I tried googling it and I only get results from people who want to search in a buffer or to grep the filesystem.

That is not what I want. I want to filter the text of a buffer. I want the text not matching the pattern to be gone and I don't want to grep the files in my filesystem.

Is this possible? I'm currently saving the output of the buffer to a file and doing this in a shell:

more file.txt | grep pattern
Drew
  • 75,699
  • 9
  • 109
  • 225
Romário
  • 123
  • 6

2 Answers2

5

I want the text not matching the pattern to be gone

  • M-x keep-lines will delete lines not matching the pattern (i.e. only keep the lines which match). flush-lines does the opposite, deleting lines which do match the pattern.
  • M-x occur will open a separate buffer showing only the matching lines (which you can use like a compilation error buffer to navigate those positions in the original buffer). This option is the closest to the 'grep' approach.
  • C-uM-x occur will show only the portion of each line which specifically matched the pattern (which is what the quoted part of your question sounds most like).
  • M-x loccur from https://elpa.gnu.org/packages/loccur.html hides/unhides the text within the original buffer (which is therefore a bit like a non-destructive keep-lines).

You can read about those built-in commands, and others, in the manual:
C-hig (emacs)Other Repeating Search

Also see (emacs)Compilation Mode regarding the convenient navigation using the next-error and previous-error commands.

Finally, note that if you do need to use grep itself, you are better off doing that inside Emacs as well (not least because you can once again jump from the results to the original locations like in a compilation buffer). There are many Emacs commands which use grep, and you can read about those at:
C-hig (emacs)Grep Searching

Tangentially, I'll recommend the third-party grep equivalent to Occur Edit mode, which you can find at https://melpa.org/#/wgrep.

phils
  • 48,657
  • 3
  • 76
  • 115
  • Amazing! Is there also any way to use `sed | sort | uniq` as well? Maybe I'm asking too much, but just in case. – Romário Sep 23 '21 at 22:34
  • 1
    @dalanicolai's answer has you sorted there. – phils Sep 23 '21 at 22:40
  • You can also use `sort-lines` and `delete-duplicate-lines` (use `C-u C-u` to properly mimic `uniq`'s adjacent line requirement) – Felipe Oct 13 '21 at 16:41
  • `occur` is the best solution for me, as sometimes I have to go back to the original buffer to look for lines above and below the match. Thank you @phils, you're a savior. – Nikhil Wagh Dec 27 '21 at 15:13
  • 1
    @NikhilWagh you might then find the numeric prefix argument behaviour of `occur` useful. This has the same effect as setting `C-h v list-matching-lines-default-context-lines`. E.g. `M-2 M-s o` to show two context lines above and below each matching line. – phils Dec 27 '21 at 22:28
1

Besides the options mentioned in phils answer, you can use shell-command-on-region for this. Select the region you'd like to 'filter' first. When prefixed with a universal argument C-u, the sent text gets replaced (you can read its docstring for more info).

I don't know your exact usecase, but generally swiper or helm-swoop provide similar and generally more useful functionality.

dalanicolai
  • 6,108
  • 7
  • 23