4

tree has a -d option to "List directories only.". However, I cannot seem to find an option to "List files only." I have looked through the man page, but I cannot seem to find an option for listing only files.

  • 3
    If you listed only files, you wouldn't have much of a tree. Its like having leaves with no branches. Why not just use the find command: find -type f .? – Tim S. Sep 28 '15 at 16:19
  • find works, but I'd personally rather do things with tree since it's much easier for me to use and does not search hidden files/folders automatically. – stiemannkj1 Sep 28 '15 at 21:11
  • 2
    The whole point of tree is to output the directory structure. Omitting directories is antithetical to it's design. – Tim S. Sep 28 '15 at 22:58
  • @TimS. thanks, ultimately I just wanted a command that lists all the files in a directory, so gfind ./ -type f works much better. I can't even remember why I wanted to use tree at this point. – stiemannkj1 Jun 27 '16 at 20:34
4

As others have said in the comments, listing only non-directories doesn't exactly mesh with the purpose of the tree command.

However, listing only the files in the current directory is not unusual if you're like me and prefer to use a customized tree over ls (and maybe you've even aliased ls to tree with your preferred flags and arguments).

Leveraging a combination of tree and grep will get you what you want:

$ tree -F
.
├── file1.txt
├── file5.txt
├── parent_dir1/
│   ├── child_dir/
│   ├── file2.txt
│   └── file3.txt
└── parent_dir2/
    └── child_dir2/
        └── file4.txt

4 directories, 4 files
$ tree -FL 1 | grep -v /$
.
├── file1.txt
├── file5.txt

2 directories, 1 file

The 'F' flag causes tree to append a '/' to directories, and the 'v' flag to grep inverts the given pattern, which matches all lines ending in '/'.

You'll notice that even the summary at the end is still applicable, despite the fact that the directories aren't actually being displayed.

Once you go more than one level down, the tree structure dominates and things get a bit weird.

$ tree -FL 3 | grep -v /$
.
├── file1.txt
├── file5.txt
│   ├── file2.txt
│   └── file3.txt
        └── file4.txt

4 directories, 4 files

EDIT

Also, if the sort of broken tree output bothers you (i.e. the fact that some files are prefaced by the '├─' character instead of the '└─' character, and the multi-level version just seems to trail off...), you can fix this by sorting the output, directories first.

$ tree --dirsfirst -FL 1 | grep -v /$
.
├── file1.txt
└── file5.txt

2 directories, 1 file
$ tree --dirsfirst -FL 3 | grep -v /$
.
│   ├── file2.txt
│   └── file3.txt
│       └── file4.txt
├── file1.txt
└── file5.txt
4 directories, 5 files

I think this actually makes the node-less tree structure more readable, as well.

  • Thanks! It's been so long that I forgot that I asked this (and why I asked this). Your solution seems to work well. I think I was trying to list the full file path of all files in a directory. I've used find instead which is probably recommended, but with your answer, I can achieve a similar result with tree -F -f -i | grep -v '[/]$'. – stiemannkj1 Jun 27 '16 at 20:29
4

Consider the following command:

tree -ifF /usr/java/default/jre/lib/images | grep -v '/$'

/usr/java/default/jre/lib/images
/usr/java/default/jre/lib/images/cursors/cursors.properties
/usr/java/default/jre/lib/images/cursors/invalid32x32.gif
/usr/java/default/jre/lib/images/cursors/motif_CopyDrop32x32.gif
/usr/java/default/jre/lib/images/cursors/motif_CopyNoDrop32x32.gif
/usr/java/default/jre/lib/images/cursors/motif_LinkDrop32x32.gif
/usr/java/default/jre/lib/images/cursors/motif_LinkNoDrop32x32.gif
/usr/java/default/jre/lib/images/cursors/motif_MoveDrop32x32.gif
/usr/java/default/jre/lib/images/cursors/motif_MoveNoDrop32x32.gif
/usr/java/default/jre/lib/images/icons/sun-java_HighContrastInverse.png
/usr/java/default/jre/lib/images/icons/sun-java_HighContrast.png
/usr/java/default/jre/lib/images/icons/sun-java_LowContrast.png
/usr/java/default/jre/lib/images/icons/sun-java.png

2 directories, 12 files

The -i and -f arguments cause tree to output full paths on each line, rather than indenting. The -F argument causes it to append an / to directory names, which are filtered out by the inverted grep (grep -v '/$').

I often use a variant of this to help me impatiently watch the contents of an output directory (and its subdirectories) for activity while running some other command...

watch exec "tree -ifFsD /var/local/myapp/data | grep -v '/$'"

  • Nice! This is more useful than my answer if knowing the path to the file is important; my solution is better for getting a sort of bird's eye view of the leaves of a directory tree. – DesAdams Feb 9 at 0:19

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.