How to list folders in bash without the trailing /

9,410

Solution 1

To get only directories but omit the slash:

ls -d */ | sed 's#/##'

Or you'll have to use something like find . -type d -maxdepth 1 (but this introduces ./ prefixing)

Solution 2

With find (this will also get rid of the ./ or /path/to/ that would normally be prepended while using find):

find . -maxdepth 1 -type d -printf '%f\n'

The above command will include . and also dotfiles (which would normally be hidden). To avoid all directories beginning with a dot (at least with GNU find):

find . -maxdepth 1 -type d ! -name '.*' -printf '%f\n'

If you want to see hidden directories, but don't want ., you can use (again, only tested on GNU find, YMMV with other versions of find):

find . -maxdepth 1 -mindepth 1 -type d -printf '%f\n'

Pure bash:

for f in */; do echo "${f%/}"; done

The following is a bit of a cheat, since it actually replaces the / with a blank space (so not really useful in scripts, but if all you want is slightly prettier output you might like it):

printf '%s\b \n' */

Alternatively, you can use zsh instead of bash and take advantage of its glob qualifiers:

ls -d *(/)

Solution 3

Parsing output of ls is really a bad idea because the output format of ls is not guaranteed.

Here is a solution which does not need ls and thus does not depend on ls output formatting:

echo */ | sed s#/##g

Unfortunately the code above will not work correctly with directory names containing spaces. Because of this it is better to separate the list items by newlines or NULL characters. It is not easy to separate the arguments by something else than space without iterating them in a shell cycle.

Solution utilizing / to identify where newline should be put:

echo -n */ | sed 's#/ \?#\n#g'

Solution which utilizes changed parameter expansion separator:

nsplit() { IFS=$'\n' ; echo "$*" | sed 's#/$##' ; } ; nsplit */

Solution 4

You can use

ls -d */ | awk -F/ '{print$1}'

it pipes the ls output to awk and tells it to consider the / as field delimiter, and to print the first field only

Share:
9,410

Related videos on Youtube

Wyatt_LandWalker
Author by

Wyatt_LandWalker

I'm Wyatt_LandWalker; There is no need to say more.

Updated on September 18, 2022

Comments

  • Wyatt_LandWalker
    Wyatt_LandWalker over 1 year

    I know

    ls -d */
    

    lists all folder in current directory as dir1/ dir2/ dir3/.

    Is there the possibility in a bash script to show folders as dir1 dir2 dir3?

    • mpy
      mpy over 10 years
      That sounds as if you want to parse the output of ls... which is in general a bad idea. What do you want to achieve in your script? I'd bet, there'll be a better way to accomplish that.
    • slhck
      slhck over 10 years
      I'm curious as well. Why do you need this?
    • Wyatt_LandWalker
      Wyatt_LandWalker over 10 years
      For a script that can discriminate folders from normal files..
    • slhck
      slhck over 10 years
      ls should really only be used in interactive terminal sessions to look at the contents. If you're scripting and you need to do things to files or directories, use find with -type f or -type d, or iterate over *. For example for foo in *; do …; done. You can then use if [[ -f "$foo" ]] and if [[ -d "$foo" ]] to check if it's a file or directory, respectively. See also the XY Problem – generally it's better to show the script you have and tell us what you really need to achieve. That way you'll get a better answer.
  • Teun Vink
    Teun Vink over 10 years
    Oh, you only want to list directories? That wasn't clear from your original question. I don't think ls dan do that out of the box. ls -d */ | sed 's#/##' does the trick or you'll have to use something like find . -type d -maxdepth 1 (but this introduces './' prefixing).
  • Wyatt_LandWalker
    Wyatt_LandWalker over 10 years
    ls -d */ | sed 's#/##' Is perfect! Tanks!
  • Alex Allen
    Alex Allen over 10 years
    With your find command, you will also find ./, which is not in ls -d */
  • evilsoup
    evilsoup over 10 years
    @Bernhard good catch.
  • kayleeFrye_onDeck
    kayleeFrye_onDeck about 8 years
    I'm using MinTTY, and not sure why this doesn't work... I always get the slashes. COMPUTER+UserName@Computer MINGW64 /c/testbed $ ls -d */ | sed 's#/##' New folder (2)/ New folder (3)/ New folder/
  • phuclv
    phuclv over 5 years
    instead of sed 's#/##' just use tr -d'/'. But again, piping ls output will fail if folder names contain new lines unix.stackexchange.com/q/128985/44425