1146

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

模式究竟是*/做什么的?

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

4

28 回答 28

1199

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

于 2013-01-16T06:11:28.673 回答
561

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

1.使用echo

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

cs/ draft/ files/ hacks/ masters/ static/  
cs/code/ files/images/ static/images/ static/stylesheets/  

2.ls仅使用

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

cs/     files/      masters/  
draft/  hacks/      static/  

或作为列表(带有详细信息):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  

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

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

cs  
draft  
files  
hacks  
masters  
static

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

cs/  
draft/  
files/  
hacks/  
masters/  
static/
于 2013-06-09T12:21:33.690 回答
117

我用:

ls -d */ | cut -f1 -d'/'

这会创建一个没有斜杠的单列 - 在脚本中很有用。

于 2014-02-27T15:19:39.010 回答
73

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

find /home/alice/Documents -maxdepth 1 -type d

对于所有带有子文件夹文件夹:

find /home/alice/Documents -type d
于 2014-07-23T08:30:26.653 回答
44

四个(更多)可靠的选择。

未加引号的星号*将被 shell 解释为模式(glob)。shell 将在路径名扩展中使用它。然后它将生成与该模式匹配的文件名列表。

一个简单的星号将匹配 PWD(当前工作目录)中的所有文件名。一个更复杂的模式 as*/将匹配所有以 . 结尾的文件名/。因此,所有目录。这就是为什么命令:

1.-回声。

echo */
echo ./*/              ### Avoid misinterpreting filenames like "-e dir"

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


要对此进行测试:创建一个mkdir名为 test-dir 的目录 ( ),然后cd进入其中:

mkdir test-dir; cd test-dir

创建一些目录:

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:

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

./--/ ./-/ ./*/ ./cs/ ./dir with spaces/ ./draft/ ./files/ ./-h/
./masters/ ./-n/ ./static/ ./-v var/

但是文件名中的空格使阅读有点混乱。


如果不是echo,我们使用ls. 外壳仍然是扩展文件名列表的东西。shell 是在 PWD 中获取目录列表的原因。使其列出当前目录条目而不是每个目录的内容的选项(默认情况下)-dls

ls -d */

但是,此命令(有点)不太可靠。它会因上面列出的奇怪的命名文件而失败。它会被几个名字窒息。您需要一一擦除,直到找到有问题的。

2.- ls

GNUls将接受“选项结束”( --) 键。

ls -d ./*/                     ### More reliable BSD ls
ls -d -- */                    ### More reliable GNU ls

3.-printf

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

$ printf "%s\n" */        ### Correct even with "-", spaces or newlines.

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

$ set -- */; printf "%s\n" "${@%/}"        ### Correct with spaces and newlines.

像这样的尝试

$ for i in $(ls -d */); do echo ${i%%/}; done

将失败:

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

4.- 功能

最后,在函数中使用参数列表不会影响当前运行的 shell 的参数列表。简单地

$ listdirs(){ set -- */; printf "%s\n" "${@%/}"; }
$ listdirs

提供此列表:

--
-
*
cs
dir with spaces
draft
files
-h
masters
-n
static
-v var

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

于 2015-07-24T06:02:46.583 回答
26

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

$ tree
.
├── config.dat
├── data
│   ├── data1.bin
│   ├── data2.inf
│   └── sql
|   │   └── data3.sql
├── images
│   ├── background.jpg
│   ├── icon.gif
│   └── logo.jpg
├── program.exe
└── readme.txt

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

$ tree -dfi
.
./data
./data/sql
./images

论据是:

-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.

如果你想要绝对路径,你可以从指定当前目录的完整路径开始:

$ tree -dfi "$(pwd)"
/home/alice/Documents
/home/alice/Documents/data
/home/alice/Documents/data/sql
/home/alice/Documents/images

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

$ tree -dfi -L 1 "$(pwd)"
/home/alice/Documents
/home/alice/Documents/data
/home/alice/Documents/images

可以看到更多的论点man tree

于 2015-06-16T15:30:39.013 回答
18

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

[prompt]$ ls -d */
app//  cgi-bin//  lib//        pub//

这可能是因为您的外壳或会话配置文件将ls命令别名为包含该标志的ls版本。-F该标志将一个字符附加到每个输出名称(不是纯文件),指示它的类型。所以一个斜线来自匹配模式'*/',另一个斜线是附加的类型指示符。

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

\ls -d */
于 2016-10-28T23:05:32.990 回答
16

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

这里的许多答案实际上并没有使用ls(或仅在微不足道的意义上使用它ls -d,而使用通配符进行实际的子目录匹配。真正的ls解决方案很有用,因为它允许使用ls排序选项等选项。

排除符号链接

ls已经给出了一种使用的解决方案,但它与其他解决方案的不同之处在于它排除了指向目录的符号链接:

ls -l | grep '^d'

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

包括符号链接

在应该包含指向目录的符号链接的(可能更常见的)情况下,我们可以使用-p选项 of ls,这使得它在目录名称(包括符号链接的)后面附加一个斜杠字符:

ls -1p | grep '/$'

或者,去掉尾部的斜杠:

ls -1p | grep '/$' | sed 's/\/$//'

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

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

ls -1p | grep -P '(?=/$)'
于 2017-02-25T10:05:02.177 回答
14

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

ls -1d */

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

ls -1d */ | cut -c 1- | rev | cut -c 2- | rev | sort

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

于 2018-12-10T20:49:46.093 回答
12

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

ls -l | grep "^d" | awk -F" " '{print $9}'

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

ls -Al | grep "^d" | awk -F" " '{print $9}'

或者

find -maxdepth 1 -type d | awk -F"./" '{print $2}'
于 2015-08-29T10:21:43.497 回答
12

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

alias lsd='ls -ld */'

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

于 2016-06-02T23:02:43.910 回答
8

仅列出目录

ls -l | grep ^d

仅列出文件

ls -l | grep -v ^d 

或者你也可以这样做:

ls -ld */
于 2018-08-13T12:03:46.530 回答
7

要显示不带的文件夹列表/

ls -d */|sed 's|[/]||g'
于 2014-10-31T04:07:30.103 回答
7

试试这个。它适用于所有 Linux 发行版。

ls -ltr | grep drw
于 2018-06-22T21:49:19.100 回答
6

这是我正在使用的

ls -d1 /Directory/Path/*;
于 2015-01-15T18:10:23.917 回答
4

测试该项目是否是一个目录test -d

for i in $(ls); do test -d $i && echo $i ; done
于 2017-06-14T14:48:03.117 回答
3

*/是匹配当前目录中目录的文件名匹配模式。

只列出目录,我喜欢这个功能:

# Long list only directories
llod () {
  ls -l --color=always "$@" | grep --color=never '^d'
}

把它放在你的.bashrc文件中。

使用示例:

llod       # Long listing of all directories in current directory
llod -tr   # Same but in chronological order oldest first
llod -d a* # Limit to directories beginning with letter 'a'
llod -d .* # Limit to hidden directories

-i注意:如果您使用该选项,它将中断。这是一个修复:

# Long list only directories
llod () {
  ls -l --color=always "$@" | egrep --color=never '^d|^[[:digit:]]+ d'
}
于 2015-03-25T20:16:01.673 回答
3

仅供参考,如果您想在多行中打印所有文件,您可以执行一个ls -1将每个文件打印在单独行中的操作。文件 1 文件 2 文件 3

于 2016-02-15T14:40:09.917 回答
3
file * | grep directory

输出(在我的机器上)——

[root@rhel6 ~]# file * | grep directory
mongo-example-master:    directory
nostarch:                directory
scriptzz:                directory
splunk:                  directory
testdir:                 directory

使用cut可以进一步细化上述输出:

file * | grep directory | cut -d':' -f1
mongo-example-master
nostarch
scriptzz
splunk
testdir

* could be replaced with any path that's permitted
 file - determine file type
 grep - searches for string named directory
 -d - to specify a field delimiter
 -f1 - denotes field 1
于 2017-10-05T18:56:52.103 回答
3

ls 和 awk(没有 grep)

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

ls -l | awk '/^d/ {print $9}'

where ls -llist files with permisions
awkfilter output
'/^d/'regularexpresion 仅搜索以字母开头的行d(作为目录)查看第一行 - 权限
{print}将打印所有列
{print $9}将仅打印输出中的第 9 列(名称)ls -l

非常简单干净

于 2021-08-18T15:12:48.873 回答
2

我部分解决了它:

cd "/path/to/pricipal/folder"

for i in $(ls -d .*/); do sudo ln -s "$PWD"/${i%%/} /home/inukaze/${i%%/}; done

 

    ln: «/home/inukaze/./.»: can't overwrite a directory
    ln: «/home/inukaze/../..»: can't overwrite a directory
    ln: accesing to «/home/inukaze/.config»: too much symbolics links levels
    ln: accesing to «/home/inukaze/.disruptive»: too much symbolics links levels
    ln: accesing to «/home/inukaze/innovations»: too much symbolics links levels
    ln: accesing to «/home/inukaze/sarl»: too much symbolics links levels
    ln: accesing to «/home/inukaze/.e_old»: too much symbolics links levels
    ln: accesing to «/home/inukaze/.gnome2_private»: too much symbolics links levels
    ln: accesing to «/home/inukaze/.gvfs»: too much symbolics links levels
    ln: accesing to «/home/inukaze/.kde»: too much symbolics links levels
    ln: accesing to «/home/inukaze/.local»: too much symbolics links levels
    ln: accesing to «/home/inukaze/.xVideoServiceThief»: too much symbolics links levels

好吧,这减少了我的主要部分:)

于 2014-05-09T03:32:09.437 回答
2

仅从“此处”列出目录的单行代码。

带文件数。

for i in `ls -d */`; do g=`find ./$i -type f -print| wc -l`; echo "Directory $i contains $g files."; done
于 2014-07-16T21:04:27.400 回答
2

使用 Perl:

ls | perl -nle 'print if -d;'
于 2017-10-20T21:15:28.917 回答
2

这是一个使用的变体,它仅在单独的行上输出目录名称,是的,它很难看,但是嘿,它可以工作。

tree -d | grep -E '^[├|└]' | cut -d ' ' -f2

或使用 awk

tree -d | grep -E '^[├|└]' | awk '{print $2}'

但是,这可能会更好,并且会保留/之后的目录名称。

ls -l | awk '/^d/{print $9}'
于 2019-08-29T14:26:40.377 回答
1

添加使其完整循环,检索每个文件夹的路径,使用 Albert 的答案以及 Gordans 的组合。那应该很有用。

for i in $(ls -d /pathto/parent/folder/*/); do echo ${i%%/}; done

输出:

/pathto/parent/folder/childfolder1/
/pathto/parent/folder/childfolder2/
/pathto/parent/folder/childfolder3/
/pathto/parent/folder/childfolder4/
/pathto/parent/folder/childfolder5/
/pathto/parent/folder/childfolder6/
/pathto/parent/folder/childfolder7/
/pathto/parent/folder/childfolder8/
于 2014-12-30T05:45:28.980 回答
1

这是我用于仅列出目录名称的内容:

ls -1d /some/folder/*/ | awk -F "/" "{print \$(NF-1)}"
于 2018-11-23T14:31:12.403 回答
1

回答原来的问题,与本身*/无关;ls它是由 shell/Bash 在称为globbing的过程中完成的。

这就是为什么echo */ls -d */输出相同的元素。(该-d标志ls输出目录名称而不是目录的内容。)

于 2018-11-26T08:40:00.917 回答
1

如果您的文件夹名称中有空间 $9 print 将不起作用,请尝试以下命令

ls -l yourfolder/alldata/ | grep '^d' | awk '{print $9" " $10}'

输出

ls -l yourfolder/alldata/ | grep '^d' | awk '{print $9" " $10}'
testing_Data 
Folder 1
于 2021-07-05T12:32:34.447 回答