Linux / UNIX List Just Directories Or Directory Names

How do I list just directory names on a Linux and UNIX-like operating systems? How can I list directories only in Linux?

Linux or UNIX-like system use the ls command to list files and directories. However, ls does not have an option to list only directories.
Tutorial details
DifficultyEasy (rss)
Root privilegesNo
RequirementsNone
Time1m
You can use combination of ls command and grep command to list directory names only. You can use the find command too. In this quick tutorial you will learn how to list only directories in Linux or UNIX.

ADVERTISEMENTS

Display or list all directories in Unix

Type the following command:
$ ls -l | grep `^d'
$ ls -l | egrep `^d'

Or better try the following ls command only to list directories for the current directory:
$ ls -d */
Sample outputs:

Fig.01: List Directories in Unix and Linux Systems

Fig.01: List Directories in Unix and Linux Systems

Linux list only directories using ls command

Run the following ls command:
ls -d */

Linux or Unix List Just Directories using ls command

Listing only directories using ls command in Linux or Unix-like systems

Linux Display or list only files

Type the following command to display list only files in Linux or Unix:
$ ls -l | egrep -v '^d'
$ ls -l | egrep -v '^d'

The grep command is used to searches input. It will filter out directories name by matching first character ‘d‘. To reverse effect i.e. just to display files you need to pass the -v option. It invert the sense of matching, to select non-matching lines.

Task: Create bash shell aliases to save time

You can create two aliases as follows to list only directories and files.
alias lf="ls -l | egrep -v '^d'"
alias ldir='ls -d */'
##alias ldir="ls -l | egrep '^d'"

Put above two aliases in your bash shell startup file:
$ cd
$ vi .bash_profile

Append two lines:
alias lf="ls -l | egrep -v '^d'"
alias ldir='ls -d */'
#alias ldir="ls -l | egrep '^d'"

Save and close the file in vim. Now just type lf – to list files. Again run ldir to list directories only:
$ cd /etc
$ lf

Sample outputs:

-rw-r--r--   1 root root      2149 2006-09-04 23:25 adduser.conf
-rw-r--r--   1 root root        44 2006-09-29 05:11 adjtime
-rw-r--r--   1 root root       197 2006-09-04 23:48 aliases
-rw-------   1 root root       144 2002-01-18 13:43 at.deny
-rw-r--r--   1 root root       162 2006-09-22 23:24 aumixrc
-rw-r--r--   1 root root        28 2006-09-22 23:24 aumixrc1
....
..
....

List directory names only:
$ cd /etc
$ ldir

Sample outputs:

drwxr-xr-x   4 root root      4096 2006-09-22 16:41 alsa
drwxr-xr-x   2 root root      4096 2006-09-20 20:59 alternatives
drwxr-xr-x   6 root root      4096 2006-09-22 16:41 apm
drwxr-xr-x   3 root root      4096 2006-09-07 02:51 apt
drwxr-xr-x   2 root root      4096 2006-09-08 01:46 bash_completion.d
....
.....
.

Use find command to list either files or directories on Linux

The find command can be used as follows to list all directories in /nas, enter:

find /nas -type d
find /nas -type d -ls
find . -type d -ls

Sample outputs:

1070785    8 drwxrwxrwt   8 root     root         4096 Jul  5 07:12 .
1070797    8 drwx------   2 root     root         4096 Jul  4 07:22 ./orbit-root
1070843    8 drwxr-xr-x   2 root     root         4096 Jun 16 18:55 ./w
1070789    8 drwxr-xr-x  10 root     root         4096 Jun 17 14:54 ./b
1071340    8 drwxr-xr-x   2 root     root         4096 Jun 16 18:55 ./b/init.d
1071581    8 drwxr-xr-x   3 root     root         4096 Jun 16 18:55 ./b/bind
1071584    8 drwxr-xr-x   2 root     root         4096 Jun 16 18:55 ./b/bind/bak
1071617    8 drwxr-xr-x   2 root     root         4096 Jun 16 18:55 ./b/fw
1071628    8 drwxr-xr-x   8 root     root         4096 Jun 16 18:55 ./b/scripts

Pass the -maxdepth 0 to limit listing to the starting-points i.e. the current working directory only:
find /path/to/dir -maxdepth 1 -type d
find . -maxdepth 1 -type d
find . -maxdepth 1 -type d -ls

Listing only directories using the find command in Linux

Listing only directories using the find command in Linux

Putting it all together

Say you want to find all directories ending with .bak extension and delete it, run the following find command in the current directory:
find . -type d -iname ".bak" -delete
Verify it:
find . -type d -iname ".bak" -ls
The following shell script does two things for Apache/Nginx/Lighttpd Webroot such as /webroot/:

  1. First, finds all files and directories and set permission to read-only for security reasons.
  2. Second, it allows our web server to read files regardless of permission so that we don’t get an HTTP/403 error.

In other words, all write permissions are removed from Webroot. The server/web-app can only read files but can not alter any files or upload any files. It helps reduces attack surfaces provided that you configure the rest of the server and web application firewall correctly.

#!/usr/bin/env bash
# Purpose: Remove all write permissions from Apache/Nginx WebRoot. Make it read-only
# Author: Vivek Gite {https://www.cyberciti.biz} under GPL v2.0+
# -----------------------------------------------------------------------------------
_dp="0445" #dir read-only and allow nginx/php/perl-cgi to read it
_fp="0444" #file read-only
_dir="$1"
_user="www-nixcraft"
_group="www-nixcraft"
_chown="/bin/chown"
_chmod="/bin/chmod"
_find="/usr/bin/find"
_xargs="/usr/bin/xargs"
 
# die if $_dir not found
[ $# -eq 0 ] && { echo "Usage: $0 dirname"; exit 1; }
 
# Get base and dir names from arg
_dn="$(dirname $_dir)"
_bn="$(basename $_dir)"
 
# Avoid working on / 
[ "$_dn" == "$_bn" ] && { echo "$0: Sorry, can't work on root path."; exit 1; }
 
# Let us get started 
if [ -d "$_dir" -o -e "$_dir" ]
then
	echo "Chowning $_dir to $_user:$_group ..."
	$_chown -R $_user:$_group "$_dir"
 
	echo "Setting $_dir perm to $_fp ..."
	$_chmod -R $_fp "$_dir"
 
	if [ -d "$_dir" ] 
	then
		echo "Allowing php/perl/our webserver to read files in all subdirs..."
		$_find "$_dir" -type d -print0 | $_xargs -0 -I {} $_chmod $_dp "{}"
	fi
else
	echo "Error: $_dir not found."
fi

We can runt it as follows:
/path/to/read-only-webroot.sh /webroot/
/path/to/read-only-webroot.sh /home/httpd

Conclusion

We explained how to list the directories only using various command-line options in Linux and Unix-like operating systems.

🐧 Get the latest tutorials on SysAdmin, Linux/Unix, Open Source/DevOps topics:
CategoryList of Unix and Linux commands
File Managementcat
FirewallCentOS 8 OpenSUSE RHEL 8 Ubuntu 16.04 Ubuntu 18.04 Ubuntu 20.04
Network Utilitiesdig host ip nmap
OpenVPNCentOS 7 CentOS 8 Debian 10 Debian 8/9 Ubuntu 18.04 Ubuntu 20.04
Package Managerapk apt
Processes Managementbg chroot cron disown fg jobs killall kill pidof pstree pwdx time
Searchinggrep whereis which
User Informationgroups id lastcomm last lid/libuser-lid logname members users whoami who w
WireGuard VPNCentOS 8 Debian 10 Firewall Ubuntu 20.04

ADVERTISEMENTS
56 comments… add one
  • Eric Apr 26, 2007 @ 13:07

    To get just file names without the long list data:

    ls -l | grep ‘^d’ | awk ‘{ print $9 }’

    Or

    for foo in *; do if [ -d $foo ]; then print -n ” $foo”; else false; fi; done

    • Basem Mar 25, 2016 @ 20:25

      good job

  • Lingerance Sep 18, 2007 @ 7:39

    find . -type d -maxdepth 1

  • mysurface Sep 21, 2007 @ 0:15

    ls -d */

    or for hidden directories
    ls -d .*/

  • 🐧 nixCraft Sep 21, 2007 @ 12:52

    Thanks for contributing all other tips :)

  • Vinayak Sep 26, 2007 @ 5:56

    Thanks a lot for nice recipe… :-)

  • Michel Roig Oct 1, 2007 @ 14:48

    To get just the subdirectories names

    find . -type d -maxdepth 1 -exec basename {} \;

    However, in this case you also get the directory itself! To avoid this, add mindepth 1:

    find . -type d -maxdepth 1 -mindepth 1 -exec basename {} \;

  • Eugenio Nov 18, 2007 @ 15:12

    For some reasons on FAT fs

    ls -d */

    is not working. But this works on any filesystem:

    ls -d ./*/

  • Suresh M Jan 4, 2008 @ 10:52

    echo */

  • Al Jan 11, 2009 @ 17:19

    mysurface — you are the man!

  • biodafes Jan 21, 2009 @ 1:18

    (folders)
    ls -F | grep /
    (files)
    ls -F | grep -v /

  • Mahantesh Biradar Jan 30, 2009 @ 5:13

    Lists all the subdirectories in the current directory..

    ls -R | grep ./

  • Gareth Reeman May 1, 2009 @ 18:19

    can some1 please help me i need to know what the significant effects are of the following characters in unix filenames. 2 dots / 1 dot / tilde or “squiggle”
    ..
    .
    ~

    • 🐧 nixCraft May 1, 2009 @ 20:47

      . Current directory
      .. Parent directory
      ~ Your home directory

  • Dennis Quek May 5, 2009 @ 7:35

    Can you just list the directories name, without the permission, datetime, and etc … ?

    • Muzaffar Feb 26, 2016 @ 17:34

      just type ls

  • kopla May 8, 2009 @ 10:22

    Thanx, nice post. I was just thinking of doing it with awk but couldnt get the wildcard working. Now I am one step ahead in my shell knowledge ^^
    To Dennis Quek above :
    A rather dirty solution but does the job.

    ls -l | egrep ‘^d’ | awk ‘$1=” “‘ | awk ‘$1=” “‘ | awk ‘$1=” “‘ | awk ‘$1=” “‘ | awk ‘$1=” “‘ | awk ‘$1=” “‘| awk ‘$1=” “‘| awk ‘$1=” “‘

    (forgive me if seeing this code gives someone a heart attack, all i can say is that I’m still learning :P )
    I would love if someone can give my code a neater look :)

    • Ashish Jun 20, 2011 @ 15:58

      A cleaner Recipe for the same using AWK :

      ls -l | egrep ‘^d’ | awk ‘{ print $9}’

      another alternate is bit clumsy :

      ls -l | egrep ‘^d’ | awk ‘$1=” “,$2=” “‘ | awk ‘$1=” “,$2=” “‘ | awk ‘$1=” “,$2=” “‘ | awk ‘$1=” “,$2=” “‘

      Another Simpler and Faster way out to get the Desired result :

      ls -l|grep ‘^d’

  • kopla May 8, 2009 @ 10:34

    oops! didnt read the other comments. Already many nice solutions have been posted :P

  • jagan Jun 30, 2009 @ 12:29

    i used to the $ du command to retrieve all directory names.
    $ du

  • Aditya Jul 28, 2009 @ 14:38

    > i used to the $ du command to retrieve all directory names.
    Jagan,
    du is used to calculate Disk Usage. I want to know did you tweak this command to display directory listing in pwd. Please explain.

  • anon Oct 7, 2009 @ 18:36

    $ /bin/ls -l | grep “^d” | cut -d’ ‘ -f8
    it’s a neat trick on linux systems.

    i’m using /bin/ls and not ls because it may be aliased

  • Amit Nagwanshi Oct 20, 2009 @ 5:30

    one can list directory i simple and easy way by :
    1. ls -ltr | grep -e d
    2. ls -ld */
    3. du

    third one is the most easiest way. :-)

  • Amr Oct 23, 2009 @ 7:58

    I tried with both GNU ls and BSD one and the best option is as someone else posted above:

    ls -ld */

  • Mohammed asif Dec 9, 2009 @ 11:29

    i renamed a directory name with a space in between the directory name within GUI(Graphical User Interface)
    which is allowed and now in the shell prompt i.e. in the terminal command mode i want to enter the directory which has a space in between but it does not allows to enter into that directory it says “INVALID DIRECTORY”
    is their any alternative solution or trick to enter into the directory with the name having space.please explain
    the directory name is “file data”
    i tried with — $cd file data but it didnt work out.

  • Sirdude Feb 25, 2010 @ 18:27

    nice stuff!

    i learned a lot from the original post, but the comments are a treasure trove!

    one thing about the original post, you have a back tick instead of a single quote in the 1st two snippets
    ls -l | egrep `^d’ for example should be ls -l | egrep ‘^d’ for the copy / pasters

    thanks again ;)

  • newbee1 Mar 3, 2010 @ 18:52

    if you wanted to pull a date from the directory to only list files from datea/timea through dateb/timeb (say March 2 at 6:00 AM to March 8 at 6:00 AM) and move into a new file the output, how is this accomplished? I tried this but no output
    #!/bin/bash
    FILES=’ls -A1′
    OUTFILE=”c:/temp/RRDfilesinrange.txt”
    STARTDATE=’date –utc –date “2010-02-27 06:00:00” %s’
    ENDDATE=’date –utc –date “2010-03-02 06:00:00” %s’
    cd C: temp/tsfr-complete
    for f in $FILES
    do
    if [ -f $f ]; then
    FDATE=’stat -c “%Z” $f’
    if [ $FDATE -ge $STARTDATE ]; then
    if [ $FDATE -le $ENDDATE ]; then
    ‘echo $f >> $OUTFILE’
    fi
    fi
    fi
    done

  • Davis Apr 27, 2010 @ 2:17

    How do you get the directory listing to display only: the file name, the user that owns the file and that user’s permissions?

  • balarajangeetha Aug 4, 2010 @ 14:34

    //Mohammed asif December 9, 2009
    is their any alternative solution or trick to enter into the directory with the name having space.please explain//
    did you try
    cd “file data”
    or
    cd ‘file data’
    ( i.e. directory name with double quotes or single quote)
    you yourself have given the hint :-)

  • danio Aug 23, 2010 @ 10:20

    @Davis:
    ls -l | awk ‘{ print $1,$3,$9 }’

  • Volomike Oct 8, 2010 @ 2:53


    alias ldir="ls -d -1 */ | tr -d '/'"
    ldir

    • dccrowley Feb 15, 2011 @ 11:19

      works :)) Thanks

  • alireza Oct 21, 2010 @ 8:20

    Hello.
    I would like to do some batching in my linux but I couldn’t find any way of initializing an array containing folder’s location information. In short, I have data in two folders located at:
    /home/alireza/Desktop/DTIBetula101019/B2509.30
    /home/alireza/Desktop/DTIBetula101019/B2509.50

    and I want to make an array following by a loop to do some specific command inside each folder seprately like this:

    fn_list= (‘/home/alireza/Desktop/DTIBetula101019/B2509.30′,’/home/alireza/Desktop/DTIBetula101019/B2509.50’)

    for fn in ${fn_list}
    do
    cd $fn
    fsl4.1-fslmerge -t big4D 2501.45-DTI1-s007 2501.45-DTI2-s008 2501.45-DTI3-s009
    done

    can anybody help me to figure out how to specify an array that can pointed to a folder which can be reused during a for loop?

    Thanks
    /Alireza

  • asl.marc Jan 6, 2011 @ 18:53

    alias lsdir=’ls -d ./*/ | cut -d / -f 2′

    lsdir

    for i in `lsdir` ; do du -ks $i; done

  • SilversleevesX Sep 21, 2011 @ 15:26

    Commenting on Eric’s ls | grep | awk combination:
    Cygwin (1.7.9) displays 8, not 9, fields in

      ls -l

    .

    So change his “awk ‘{print 9}'” to awk ‘{print 8}’ and you’ll get more than a bunch of deadspace in mintty.

    Just in case it wasn’t already obvious. *S*

    BZT

  • Ramesh Kumar J May 30, 2012 @ 10:50

    ls -lrt | grep /

  • Prasad Jun 30, 2012 @ 6:32

    From all the above I feel the best way is …

    ls -ld */

  • James Friedman Oct 30, 2012 @ 9:53

    Thank you for a very helpful and useful post – much appreciated… – James

  • Adrian Apr 4, 2013 @ 9:34

    A sed version:

    ls -F1 | grep ‘/’ | sed ‘s/\///’

  • Nageswara Rao Orsu May 21, 2013 @ 11:29

    ls -d */ or ls -ld */ (Use these commands to display only directories in current user)
    cd /etc
    ls -ld */ ( Use these two commands to display only directories for all users including root)

  • mammy boy May 24, 2013 @ 22:28

    list of directories:
    ls -alp /

  • nn Jun 28, 2013 @ 3:10

    alias lsd=’ ls –color=always -ld */ | tr -d / ‘

  • seb Aug 8, 2013 @ 18:06

    It’s already been said but
    ls -d */
    works best for me, very simple and obvious.

  • jimbo Aug 31, 2013 @ 17:24

    alias dir=”ls -l | grep ‘^d’ | awk ‘{print \$9}'”

  • Ashish K Bajpai Oct 6, 2013 @ 18:22

    I know many good options are available but one more variation using tr & cut:

    ls -l /var|egrep ‘^d’|tr -s ‘ ‘|cut -d’ ‘ -f9

  • Daniel Jan 31, 2014 @ 6:36

    ls -F | grep / | tr -d /

  • Jon Jagger Dec 8, 2015 @ 17:19

    About
    ls -d */

    This works if there are some directories. But if there are no directories I get
    ls: cannot access */: No such file or directory

  • anon Feb 1, 2016 @ 18:26

    Doesn’t work

  • arob May 31, 2016 @ 15:11

    As stated above:
    ls -ld */
    Or, create an alias for above such as:
    alias lsd=”ls -ld */”
    Then, simply lsd will generate a long directory only list.

  • Vignesh Jun 5, 2016 @ 3:50

    Try this option
    ls -ld */
    or
    ls -ld <>/
    example: ls -ld test/

  • Ken Jul 21, 2016 @ 14:36

    Here’s one I use at work when we’re cleaning up data dirs past our retention period.
    We have a production mount with named paths containing a dated subdir.
    The asterisks are there to cover all our various common ‘feeds’. I need this in a report that a Window user will pickup via sftp, so I name the results .txt for their convenience.
    -d for directories
    -g displays directories first (shouldn’t be needed, but sometimes ‘file’ names wind up in my results and this seems to at least keep them together).
    -R …Recursive.

    ls -dgR /path/to/data/*/*/*2015* >> /path/to/employee/dir/DirList-2015.txt

  • Deepak Jul 22, 2016 @ 17:50

    I want see only file
    What is the command?
    Can any one tell

    • 🐧 Vivek Gite Jul 23, 2016 @ 9:36

      Try:

      ls -l | grep -v '^d'

      OR

      find . -maxdepth 1 -type f -ls | more

      OR

      find . -type f -ls | more
  • Tim Feb 14, 2017 @ 15:55

    Great information here! I’ve always wondered if there was a quick way to display just directories in UNIX. I sift through files with a lot of junk in them (in addition to other folders), and this command is money! Thanks for the info!

  • john May 9, 2017 @ 18:44

    can i automatically put it in .txt or .xls file?

Leave a Reply

Your email address will not be published.

Use HTML <pre>...</pre>, <code>...</code> and <kbd>...</kbd> for code samples.