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". 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! Commented Mar 17, 2022 at 17:31

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.