42

The obvious

ls -dR

does not work.

I am currently using

find /path/ -type d -ls

but the output is not what I need (plain listing of sub-folders)

Is there a way out?

  • Here's a nice bash script to print a directory tree, with colors: mama.indstate.edu/users/ice/bash/btree Easy to install, no root access needed. – aap Sep 12 '15 at 14:29
  • 1
    The real question should be: Why does ls -dR not work? – mastaBlasta Oct 1 '15 at 14:39
  • The real question should include a description of "work", so that we can answer why ls -dR "does not work". ls -dR actually does what the documentation says: "-d Directories are listed as plain files (not searched recursively)." ls -R on the other hand does list subdirectories recursively. – LarsH Apr 23 '18 at 19:51
57

Assuming you just want the name of each directory:

find /path/ -type d -print
  • 7
    +1. BTW, the '-print' arg is optional - it's default. also if a specific listing format is required it can be fed into xargs to run ls with any desired options, e.g. find /path/ -type d -print0 | xargs -0 -r ls -ld. Note the -print0 for NULL terminated output, and the matching -0 xargs arg. – cas Jul 23 '12 at 10:36
  • And if you by chance are running this on Windows and cygwin, then Windows already has a find command, so you probably should specify the path to cygwin's bin folder. – phyatt Apr 27 '15 at 19:39
10

I was looking for the same thing in the past and found this:

tree.sh

#!/bin/sh
#######################################################
#  UNIX TREE                                                            
#  Version: 2.3                                       
#  File: ~/apps/tree/tree.sh                          
#                                                     
#  Displays Structure of Directory Hierarchy          
#  -------------------------------------------------  
#  This tiny script uses "ls", "grep", and "sed"      
#  in a single command to show the nesting of         
#  sub-directories.  The setup command for PATH       
#  works with the Bash shell (the Mac OS X default).  
#                                                     
#  Setup:                                             
#     $ cd ~/apps/tree                                
#     $ chmod u+x tree.sh                             
#     $ ln -s ~/apps/tree/tree.sh ~/bin/tree          
#     $ echo "PATH=~/bin:\${PATH}" >> ~/.profile      
#                                                     
#  Usage:                                             
#     $ tree [directory]                              
#                                                     
#  Examples:                                          
#     $ tree                                          
#     $ tree /etc/opt                                 
#     $ tree ..                                       
#                                                     
#  Public Domain Software -- Free to Use as You Like  
#  http://www.centerkey.com/tree  -  By Dem Pilafian  
#######################################################

echo
if [ "$1" != "" ]  #if parameter exists, use as base folder
   then cd "$1"
   fi
pwd
ls -R | grep ":$" |   \
   sed -e 's/:$//' -e 's/[^-][^\/]*\//--/g' -e 's/^/   /' -e 's/-/|/'
# 1st sed: remove colons
# 2nd sed: replace higher level folder names with dashes
# 3rd sed: indent graph three spaces
# 4th sed: replace first dash with a vertical bar
if [ `ls -F -1 | grep "/" | wc -l` = 0 ]   # check if no folders
   then echo "   -> no sub-directories"
   fi
echo
exit

I wanted one that listed files as well and I learned about sed and wrote this:

fulltree.sh

#!/bin/sh
#############################################
# Script that displays a recursive formatted folder and file listing
# @author Corbin
# @site iamcorbin.net
#Folder Seperator
BREAK='-------------------------------------------------------------------------------------'

#Optional: if a folder is passed as an argument, run fulltree on that folder rather than the current folder
if [ "$1" != "" ]
   then cd "$1"
   fi
pwd

## Recursive Directory Listing with files
 # 1- preserve directories from being removed in 2 & 3
 # 2- strip first 4 columns
 # 3- strip size and date
 # 4- prepend '  -- ' on each line
 # 5- remove '  -- ' from directories
 # 6- remove extra lines
 # 7- Insert a line break after directories
 # 8- Put a | at the beginning of all lines
 # 9- Indent and process 1st level sub dirs
 #10- Indent and process 2nd level sub dirs
ls -Rhl | sed \
    -e 's/^\.\//x x x x 00:00 |-/' \
    -e 's/^\([^\ ]*.\)\{4\}//' \
    -e 's/.*[0-9]\{2\}:[0-9]\{2\}//' \
    -e 's/^/  -- /' \
    -e 's/\ \ --\ \ |-//'  \
    -e '/--\ $/ d' \
    -e '/^[^ ]/ i\'$BREAK \
    -e 's/^/| /' \
| sed -e '/[^/]*\//,/'$BREAK'/ s/^|/\t&/' -e '/^\t/,/'$BREAK'/ s/'$BREAK'/\t&/' -e 's/[^/]*\//\t\| /' \
| sed -e '/[^/]*\//,/'$BREAK'/ s/^\t|/\t&/' -e '/^\t\t/,/'$BREAK'/  s/'$BREAK'/\t&/' -e 's/[^/]*\//\t\t\| /' \
| sed -e '/[^/]*\//,/'$BREAK'/ s/^\t\t/\t&/' -e 's/[^/]*\//\t\t\t\| /'
echo $BREAK
  • ls -R | grep "^[.]/" | sed -e "s/:$//" -e "s/[^/]*[/]/--/g" -e "s/^/ |/" an update to tree.sh I made to handle some edge cases, latest at: centerkey.com/tree – Dem Pilafian Nov 22 '18 at 21:12
9

You can get the "tree" package, on both ArchLinux and Ubuntu it is called "tree"

So that if you're in ~/ , you can do tree -d and get a full directory listing (in a tree structure) for all of what's in ~/

  • I need plain text, new line separated listing of sub-directories, while tree seems to add its "tree" structure. And I can't seem to find a flag to disable it. – Nemo Feb 25 '12 at 23:15
  • 2
    @Capt.Nemo: For a plain listing, use: tree -dfi ... you can add --noreport to suppress the final display of the total directory count. – Peter.O Feb 26 '12 at 1:37
3

The OP doesn't specify what format of output that they want (beyond "plain listing of sub-folders").

[ 15:53. root@prod-2 /var]% ls -lDR | grep ':$' | head
 .:
 ./account:
 ./cache:
 ./cache/coolkey:
 ./cache/fontconfig:
 ./cache/logwatch:
 ./cache/man:
 ./cache/man/X11R6:
 ./cache/man/X11R6/cat1:
 ./cache/man/X11R6/cat2:...

Optionally remove the trailing : with |sed -e 's/:$//' or format it with |awk '{printf("%-92s \n",$0)}' etc.

1

With zsh and glob qualifiers:

print -rl /path/**/*(D/)

to exclude hidden directories:

print -rl /path/**/*(/)
0

For bash:

shopt -s globstar nullglob dotglob
echo /path/**/*/

The last slash / list only directories.

Option globstar activates **.
Option nullglob removes a * that match nothing.
Option dotglob to include files that start with a dot (hidden files)

protected by Community Sep 12 '15 at 15:53

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).

Would you like to answer one of these unanswered questions instead?

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