2

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:

./dirA/dirA.A/abc.txt
./dirA/dirA.A/def.txt
./dirA/dirA.A/dirA.A.A/ghi.txt
./dirA/dirA.B/jkl.txt
./dirB/mno.txt

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

./
  dirA/
    dirA.A/
      abc.txt
      def.txt
      dirA.A.A/
        ghi.txt
    dirA.B/
      jkl.txt
  dirB/
    mno.txt

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.

2
  • 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. Commented Mar 16, 2022 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
    Commented Mar 16, 2022 at 17:18

1 Answer 1

5

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:

3
  • 1
    You could add the -F option to add a trailing / to directories. Commented Mar 16, 2022 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. Commented Mar 16, 2022 at 17:43
  • @StéphaneChazelas Aah good thought. I'll update the example. Thanks!
    – loneboat
    Commented Mar 17, 2022 at 17:31

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .