56

Is there any way to list just the folders in a directory using bash commands? ( as the ls command lists all the files and folders )

That Brazilian Guy
  • 6,834
  • 10
  • 64
  • 102
SpiXel
  • 969
  • 3
  • 10
  • 14

8 Answers8

78

You can use:

ls -d -- */

Since all directories end in /, this lists only the directories in the current path. The -d option ensures that only the directory names are printed, not their contents.

Gaff
  • 18,569
  • 15
  • 57
  • 68
32

Stephen Martin's response gave a warning, and listed the current folder as well, so I'd suggest

find . -mindepth 1 -maxdepth 1 -type d

(This is on Linux; I could not find -maxdepth and -mindepth in the POSIX man page for find)

daniel kullmann
  • 635
  • 5
  • 10
  • 2
    Older question I know. While I would too initially turn to find for this task, I like the `ls -d -- */` option, as `find` will find hidden directorties too. Which can sometimes be useful, but also sometimes cause trouble. I hope this comment might help others. +1 – matchew Dec 21 '12 at 16:16
13
find . -maxdepth 1 -type d

Will list just folders. And as Teddy pointed out you'll need -maxdepth to stop it recusrsing into sub dirs

squareborg
  • 2,425
  • 2
  • 19
  • 27
7

Daniel’s answer is correct. Here are some useful additions, though.

To avoid listing hidden folders (like .git), try this:

find . -mindepth 1 -maxdepth 1 -type d  \( ! -iname ".*" \)

And to replace the dreaded dot slash at the beginning of find output in some environments, use this:

find . -mindepth 1 -maxdepth 1 -type d  \( ! -iname ".*" \) | sed 's|^\./||g'
Mathias Bynens
  • 2,441
  • 5
  • 31
  • 39
2

You're "not supposed to" parse the output of ls, or so is said. The reasoning behind is that the output is intended to be human-readable and that can make it unnecessarily complicated to parse, if I recall.

if you don't want ls or find, you may want to try filtering "*" with "[ -d ]".

I did just that, for some reason ls and find weren't working (file names with spaces and brackets I guess, or somthing else I was overlooking), then I did something along the lines of

for f in * ; do [ -d "$f" ] && echo $f is indeed a folder ; done
0

You can also use:

du

Or:

git ls-tree -d -r --name-only @
Zombo
  • 1
  • 24
  • 120
  • 163
0

Just to emphasize a thing that confused me out here, in respect to glob patterns selection; say you have this:

$ cd /tmp
$ mkdir testglob
$ for ix in {00,01,02,03} ; do mkdir testglob/mydir_${ix} ; done
$ for ix in {00,01,02,03} ; do touch testglob/myfile_${ix} ; done
$ for ix in {00,01,02,03} ; do touch testglob/mydir_${ix}.txt ; done
$ for ix in {00,01,02,03} ; do mkdir testglob/otherdir_${ix} ; done
$ tree testglob/
testglob/
├── mydir_00
├── mydir_00.txt
├── mydir_01
├── mydir_01.txt
├── mydir_02
├── mydir_02.txt
├── mydir_03
├── mydir_03.txt
├── myfile_00
├── myfile_01
├── myfile_02
├── myfile_03
├── otherdir_00
├── otherdir_01
├── otherdir_02
└── otherdir_03

8 directories, 8 files

So, say here you want to select only mydir* directories. Note that if you leave out the terminating slash, ls -d will list files as well:

$ ls -d testglob/mydir*   # also `ls -d -- testglob/mydir*`
testglob/mydir_00      testglob/mydir_01      testglob/mydir_02      testglob/mydir_03
testglob/mydir_00.txt  testglob/mydir_01.txt  testglob/mydir_02.txt  testglob/mydir_03.txt

... however, with a terminating slash, then only directories are listed:

$ ls -d testglob/mydir*/   # also `ls -d -- testglob/mydir*/`
testglob/mydir_00/  testglob/mydir_01/  testglob/mydir_02/  testglob/mydir_03/
sdaau
  • 5,316
  • 8
  • 60
  • 77
0

printf "%s\n" */ will list all directories in the $PWD.

echo */ will also work, but in a long one-line, more difficult when names have spaces.