在bash中仅使用ls列出目录:检查

Sib*_*ibi 885 directory bash ls

此命令列出当前路径中的目录: ls -d */

这个模式究竟做了*/什么?

我们如何在上面的命令(例如ls -d /home/alice/Documents)中给出绝对路径以仅列出该路径中的目录?

Gor*_*son 920

*/是一个匹配当前目录中所有子目录的模式(*将匹配所有文件子目录;将其/限制为目录).同样,要列出/ home/alice/Documents下的所有子目录,请使用ls -d /home/alice/Documents/*/

  • 请注意,`*/`将不匹配任何隐藏文件夹.要包含它们,要么明确指定它们,如`ls -d.*/*/`,或[设置`dotglob`选项](https://www.gnu.org/software/bash/manual/html_node/The- Shopt-Builtin.html#The-Shopt-Builtin)在Bash. (78认同)
  • @BinaryZebra设置nullglob会避免错误消息,但会引起更多的混淆:使用nullglob set并且没有子目录,`ls*/`会扩展为`ls`,这将列出当前目录中的所有文件.在这种情况下,我很确定这不是你想要的. (4认同)
  • `*/` 还设置要显示的子目录名称,并带有尾部斜杠。 (3认同)
  • 列出所有文件夹排除`./` `../`:`ls -d */ .[^.]*/` (2认同)

Alb*_*ert 460

完成此操作的四种方法,每种方式都有不同的输出格式

1.使用 echo

示例:echo */,echo */*/
这是我得到的:

cs/ draft/ files/ hacks/ masters/ static/  
cs/code/ files/images/ static/images/ static/stylesheets/  
Run Code Online (Sandbox Code Playgroud)

2. ls仅使用

示例:ls -d */
这正是我得到的:

cs/     files/      masters/  
draft/  hacks/      static/  
Run Code Online (Sandbox Code Playgroud)

或者作为列表(详细信息): ls -dl */

3.使用lsgrep

示例:ls -l | grep "^d" 这是我得到的:

drwxr-xr-x  24 h  staff     816 Jun  8 10:55 cs  
drwxr-xr-x   6 h  staff     204 Jun  8 10:55 draft  
drwxr-xr-x   9 h  staff     306 Jun  8 10:55 files  
drwxr-xr-x   2 h  staff      68 Jun  9 13:19 hacks  
drwxr-xr-x   6 h  staff     204 Jun  8 10:55 masters  
drwxr-xr-x   4 h  staff     136 Jun  8 10:55 static  
Run Code Online (Sandbox Code Playgroud)

4. Bash脚本(不推荐用于包含空格的文件名)

示例:for i in $(ls -d */); do echo ${i%%/}; done
这是我得到的:

cs  
draft  
files  
hacks  
masters  
static
Run Code Online (Sandbox Code Playgroud)

如果您希望将'/'作为结束字符,则命令将为: for i in $(ls -d */); do echo ${i}; done

cs/  
draft/  
files/  
hacks/  
masters/  
static/
Run Code Online (Sandbox Code Playgroud)

  • 在处理具有空格的文件夹名称时,"1."选项将导致严重的问题. (15认同)
  • 你应该注意两件小事.ls -l | grep"^ d"过滤掉目录的符号链接,而'ls -d*/'显示它们.此外,如果目标目录中根本没有目录,则'ls -d*/'将失败. (9认同)
  • **NB.**`3`对我来说明显慢于其他人.在我测试的目录中:`1`.012s,`2` .016s,`3`**.055s**,`4` .021s. (2认同)

小智 90

我用:

ls -d */ | cut -f1 -d'/'
Run Code Online (Sandbox Code Playgroud)

这将创建一个没有尾部斜杠的单个列 - 在脚本中很有用.

我的两分钱.

  • `ls`的`-1`选项也将以单列格式输出,如`ls -1 -d*/`. (18认同)
  • @ user29020应该注意,`-1`仍然为每个条目输出一个尾部斜杠. (3认同)

小智 57

对于没有子文件夹的所有文件夹:

find /home/alice/Documents -maxdepth 1 -type d
Run Code Online (Sandbox Code Playgroud)

对于包含子文件夹的所有文件夹:

find /home/alice/Documents -type d
Run Code Online (Sandbox Code Playgroud)

  • 为了匹配问题(但包括点文件),第一个应该是:`find /home/alice/Documents -maxdepth 1 -mindepth 1 -type d` 否则你包括 `/home/alice/Documents` 本身。要包含指向目录的符号链接,请以“-L”为前缀 (4认同)

小智 34

4(更多)可靠的选择.

一个不带引号的星号*将被解释为通过所述壳的图案(水珠).
shell将在路径名扩展中使用它.
然后,它将生成与模式匹配的文件名列表.
一个简单的星号将匹配PWD(当前工作目录)中的所有文件名.
一个更复杂的模式,*/将匹配所有结束的文件名/.
因此,所有目录.这就是为什么命令:

回声.

echo */
echo ./*/              ### avoid misinterpreting filenames like "-e dir"
Run Code Online (Sandbox Code Playgroud)

将(通过shell)扩展到echoPWD中的所有目录.


要测试这个:创建一个mkdir名为test-dir 的目录(),并cd在其中:

mkdir test-dir; cd test-dir
Run Code Online (Sandbox Code Playgroud)

创建一些目录:

mkdir {cs,files,masters,draft,static}   # safe directories.
mkdir {*,-,--,-v\ var,-h,-n,dir\ with\ spaces}  # some a bit less secure.
touch -- 'file with spaces' '-a' '-l' 'filename'    # and some files:
Run Code Online (Sandbox Code Playgroud)

echo ./*/即使使用奇数命名文件,该命令仍将保持可靠:

./--/ ./-/ ./*/ ./cs/ ./dir with spaces/ ./draft/ ./files/ ./-h/
./masters/ ./-n/ ./static/ ./-v var/
Run Code Online (Sandbox Code Playgroud)

但文件名中的空格使阅读有点令人困惑.


如果不是echo,我们使用ls,shell仍然是扩展文件名列表的东西.shell是获取PWD中目录列表的原因.该-d选项ls使得它列出当前目录条目,而不是每个目录的内容(如默认提交).

ls -d */
Run Code Online (Sandbox Code Playgroud)

但是,这个命令(有些)不太可靠.它将失败,上面列出了奇怪的命名文件.它会扼杀几个名字.你需要逐个擦除,直到找到有问题的那些.

2.- ls

GNU ls将接受"选项结束"(--)键.

ls -d ./*/                     ### more reliable BSD ls
ls -d -- */                    ### more reliable GNU ls
Run Code Online (Sandbox Code Playgroud)

3-的printf

要列出其自己行中的每个目录(在一列中,类似于ls -1),请使用:

$ printf "%s\n" */        ### Correct even with "-", spaces or newlines.
Run Code Online (Sandbox Code Playgroud)

而且,更好的是,我们可以删除尾随/:

$ set -- */; printf "%s\n" "${@%/}"        ### Correct with spaces and newlines.
Run Code Online (Sandbox Code Playgroud)

像这样的尝试:

$ for i in $(ls -d */); do echo ${i%%/}; done
Run Code Online (Sandbox Code Playgroud)

将失败:

  • 一些名字(ls -d */)如上所示.
  • 会受到价值的影响IFS.
  • 将在空格和制表符上拆分名称(默认情况下IFS).
  • 名称中的每个换行符将启动一个新的echo命令.

4.-功能

最后,使用函数内的参数列表不会影响当前运行的shell的参数列表.只是:

$ listdirs(){ set -- */; printf "%s\n" "${@%/}"; }
$ listdirs
Run Code Online (Sandbox Code Playgroud)

列出这个清单:

--
-
*
cs
dir with spaces
draft
files
-h
masters
-n
static
-v var
Run Code Online (Sandbox Code Playgroud)

这些选项对于几种类型的奇数文件名是安全的.


Ham*_*ner 19

tree命令在这里也很有用.默认情况下,它会将所有文件和目录显示为完整的深度,其中一些ascii字符显示目录树.

$ tree
.
??? config.dat
??? data
?   ??? data1.bin
?   ??? data2.inf
?   ??? sql
|   ?   ??? data3.sql
??? images
?   ??? background.jpg
?   ??? icon.gif
?   ??? logo.jpg
??? program.exe
??? readme.txt
Run Code Online (Sandbox Code Playgroud)

但是如果我们想要只获取目录,没有ascii树,并且使用当前目录的完整路径,那么你可以这样做:

$ tree -dfi
.
./data
./data/sql
./images
Run Code Online (Sandbox Code Playgroud)

论点是:

-d     List directories only.
-f     Prints the full path prefix for each file.
-i     Makes tree not print the indentation lines, useful when used in conjunction with the -f option.
Run Code Online (Sandbox Code Playgroud)

如果您想要绝对路径,可以先指定当前目录的完整路径:

$ tree -dfi "$(pwd)"
/home/alice/Documents
/home/alice/Documents/data
/home/alice/Documents/data/sql
/home/alice/Documents/images
Run Code Online (Sandbox Code Playgroud)

要限制子目录的数量,您可以设置子目录的最大级别-L level,例如:

$ tree -dfi -L 1 "$(pwd)"
/home/alice/Documents
/home/alice/Documents/data
/home/alice/Documents/images
Run Code Online (Sandbox Code Playgroud)

人树可以看到更多的论点


PYK*_*PYK 14

当前目录的简单列表,它是:

ls -1d */
Run Code Online (Sandbox Code Playgroud)

如果你想要它排序和清洁:

ls -1d */ | cut -c 1- | rev | cut -c 2- | rev | sort
Run Code Online (Sandbox Code Playgroud)

请记住:大写字符在排序中具有不同的行为


gwi*_*man 12

如果您想知道为什么来自'ls -d*/'的输出会给您两个尾部斜杠,例如:

[prompt]$ ls -d */    
app//  cgi-bin//  lib//        pub//
Run Code Online (Sandbox Code Playgroud)

这可能是因为你的shell或会话配置文件的某个地方将ls命令别名为包含-F标志的ls版本.该标志在每个输出名称(不是普通文件)上附加一个字符,表示它的类型.因此,一个斜杠是匹配模式'*/',另一个斜杠是附加的类型指示符.

要摆脱这个问题,你当然可以为ls定义一个不同的别名.但是,要暂时不调用别名,可以在命令前加上反斜杠:

\ ls -d*/


Dev*_*vWL 11

ls 和 awk(不带 grep)

不需要使用 grep 因为 awk 可以执行正则表达式检查,所以这样做就足够了:

ls -l | awk '/^d/ {print $9}'
Run Code Online (Sandbox Code Playgroud)

其中具有权限过滤器输出正则表达式的ls -l列表文件,仅搜索以字母开头的行(作为目录)查看第一行 - 权限将打印所有列将仅打印输出中的第 9 列(名称)
awk
'/^d/'d
{print}
{print $9}ls -l

非常简单干净


小智 10

我只是将它添加到我的.bashrc文件中(如果你只需要/想要一个会话,你也可以在命令行中输入它)

alias lsd='ls -ld */'
Run Code Online (Sandbox Code Playgroud)

然后lsd将产生所需的结果.

  • "那么lsd将产生预期的结果." 我笑 (5认同)

pyr*_*sty 9

实际ls解决方案,包括目录的符号链接

这里的许多答案实际上并没有使用ls(或者只是在平凡的意义上使用它ls -d,同时使用通配符进行实际的子目录匹配.真正的ls解决方案很有用,因为它允许使用ls选项来排序顺序等.

排除符号链接

ls已经给出了一个使用的解决方案,但它与其他解决方案有所不同,因为它将符号链接排除到目录:

ls -l | grep '^d'
Run Code Online (Sandbox Code Playgroud)

(可能通过管道传输sedawk隔离文件名)

包括符号链接

在(可能更常见的)情况下,应该包含目录的符号链接,我们可以使用以下-p选项ls:

ls -1p | grep '/$'
Run Code Online (Sandbox Code Playgroud)

或者,摆脱尾随斜杠:

ls -1p | grep '/$' | sed 's/\/$//'
Run Code Online (Sandbox Code Playgroud)

我们可以ls根据需要添加选项(如果使用长列表,-1则不再需要).

注意:如果我们想要尾部斜杠,但不希望它们突出显示grep,我们可以通过使该行的实际匹配部分为空来删除突出显示:

ls -1p | grep -P '(?=/$)'
Run Code Online (Sandbox Code Playgroud)


PHP*_*ner 8

如果不需要列出隐藏目录,我提供:

ls -l | grep "^d" | awk -F" " '{print $9}'  
Run Code Online (Sandbox Code Playgroud)

如果需要列出隐藏目录,请使用:

ls -Al | grep "^d" | awk -F" " '{print $9}'
Run Code Online (Sandbox Code Playgroud)

要么

find -maxdepth 1 -type d | awk -F"./" '{print $2}'
Run Code Online (Sandbox Code Playgroud)


tor*_*mas 8

我发现这个解决方案最舒服,我添加到列表中:

find * -maxdepth 0 -type d
Run Code Online (Sandbox Code Playgroud)

不同的是它没有./开头,文件夹名就可以用了。


小智 7

显示没有的文件夹列表 /

ls -d */|sed 's|[/]||g'
Run Code Online (Sandbox Code Playgroud)

  • 或者`ls -d1*/| tr -d"/"` (2认同)

小智 7

Try this one. It works for all Linux distribution.

ls -ltr | grep drw
Run Code Online (Sandbox Code Playgroud)

  • `ls -l | grep '^d' | grep '^d' | awk '{print $9}'` (7认同)

Vij*_*was 6

仅列出目录:

ls -l | grep ^d
Run Code Online (Sandbox Code Playgroud)

仅列出文件:

ls -l | grep -v ^d 
Run Code Online (Sandbox Code Playgroud)

或者你也可以这样做:ls -ld*/


小智 5

这是我正在使用的

ls -d1 /Directory/Path/*;

  • 它不会仅列出目录。您必须添加尾部斜杠:`ls -d1 /Directory/Path/*/` (4认同)