I'm searching a large number of text files which are organized in various subdirectories. I can run a command such as grep -lr foobar ./, and I get results like the following:


I would like some way to display these in a visual tree, similar to how the tree command works. Something roughly like this:


It seems like it'd be trivial to do this in some Python script with a stack, but I'd really like some way to do this straight from bash if there's a way to do it. So I guess I'm looking for a way to either (a) format/transform the output of grep, OR (b) some other generic "indent-by-common-prefix" utility that I've so-far been unable to find.

  • 1
    I would be strongly tempted to leave the / suffix on each level of the tree. Otherwise, there is no way to distinguish between a regular file and an empty directory. Mar 16 at 17:15
  • Good point. I'll change the example. My actual output requirements aren't very strict, just "some sort of visual tree".
    – loneboat
    Mar 16 at 17:18

1 Answer 1


I found a solution using a version of tree which is newer than what was installed on my system. Version 1.8.0 of tree (released 11/16/2018) introduced the --fromfile parameter, which reads a directory/file listing from a file (or stdin) rather than the filesystem itself and generates a tree representation:

$ grep -rl 'foobar' ./ |tree --fromfile -F .
└── ./
    ├── dirA/
    │   ├── dirA.A/
    │   │   ├── abc.txt
    │   │   ├── def.txt
    │   │   └── dirA.A.A/
    │   │       └── ghi.txt
    │   └── dirA.B/
    │       └── jkl.txt
    └── dirB/
        └── mno.txt

6 directories, 5 files

For reference:

  • 1
    You could add the -F option to add a trailing / to directories. Mar 16 at 17:41
  • It's unfortunate that tree takes a newline-delimited list on input rather than a null-delimited ones (like with the --file0-from of several GNU utilities) as that means it can't render arbitrary file names. Mar 16 at 17:43
  • @StéphaneChazelas Aah good thought. I'll update the example. Thanks!
    – loneboat
    Mar 17 at 17:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.