grep + tree how?

I want something like $ grep -rin "foo bar" but with the option to display the file location visually like tree but with the results trimmed so that only the recursive directories are displayed. It would be better if it was structured so that the directory listing is only displayed once with every location displayed within the directory tree. Like if I want to know every location where a method is called, I can quickly parse that on the command line. Anyone know of a tool that does this already or a simple technique, or do I need to script it myself?

31 points · 7 comments · view on lemmy.world

7 Comments

Botzo@lemmy.world · 13 pts · 342d (2 replies)

grep -l will get you just the filenames

tree --fromfile will read from stdin just fine

So: grep -ril "foo bar" . | tree --fromfile -a should do the trick.

Edit: removed -n from the grep incantation per below conversation.

TwilightKiddy@programming.dev · 4 pts · 342d (1 reply)

For obvious reasons, -n does not work with -l. Not that it hurts to include it, but -ril makes more sense.

Botzo@lemmy.world · 4 pts · 342d

Good point! No use for a line number when you're explicitly dumping file names. And if it did work, would likely break the pipe to tree.

I lazily copied the original and just added -l.

thingsiplay@beehaw.org · 12 pts · 342d

Combine both grep and tree commands:

grep -rl "find" | tree --fromfile -F

Edit: The rg example didn't work correclty. Not sure what I was testing. But looks like the grep variant works as intended. Please report if its not.

Another Edit, because this is fun: A simple function for your .bashrc (functions are like alias, but allow more complex code, such as arguments):

treegrep() {
    # grep:
    #   --recursive             like --directories=recurse
    #   --files-with-match      print only names of FILEs with selected lines
    # tree:
    #   --fromfile              Reads paths from files (.=stdin)
    #   -F                      Appends '/', '=', '*', '@', '|' or '>' as per ls -F.
    grep --recursive --files-with-match "${@}" |
        tree --fromfile -F
}
defragmenteur@lemmy.world · 4 pts · 342d

Try broot

solrize@lemmy.ml · 4 pts · 342d (1 reply)

I don't understand what you're asking: you want some kind of graphical display of the file structure? Grep per se doesn't do that, but maybe you could match the output against "tree" output? I generally just use M-x grep in Emacs which doesn't make a tree-like display, but lets me navigate to matched lines by clicking on them.

j4k3@piefed.world · 3 pts · 342d

The other post reply here came close enough. With the suggestion to use: tree --fromfile -a with grep. I'm still not fast enough with emacs to do stuff like this efficiently. I get lost in the documentation and do not use emacs daily.