该命令列出当前路径下的目录:

ls -d */

模式*/到底做什么?

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


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


有四种方法可以做到这一点,每种方法都有不同的输出格式

1. 使用回声

例如: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.使用ls和grep

示例: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脚本(不推荐用于包含空格的文件名)

例如:$(ls -d */)中的i;执行echo ${i%%/};完成 以下是我得到的:

cs  
draft  
files  
hacks  
masters  
static

如果你想用'/'作为结尾字符,命令将是:for i in $(ls -d */);执行echo ${i};完成

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

我使用:

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

这将创建一个没有结尾斜杠的单列——在脚本中很有用。


我用以下方法部分解决了这个问题:

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

好吧,这对我来说是主要的部分:)


只从“这里”列出目录的一行程序。

文件计数。

for i in `ls -d */`; do g=`find ./$i -type f -print| wc -l`; echo "Directory $i contains $g files."; done

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

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

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

find /home/alice/Documents -type d

显示没有/的文件夹列表:

ls -d */|sed 's|[/]||g'

再加上一个完整的循环,检索每个文件夹的路径,使用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/

这是我正在用的

ls -d1 /Directory/Path/*;

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

只列出目录,我喜欢这个函数:

# 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'
}

树命令在这里也非常有用。默认情况下,它将完整地显示所有文件和目录,并使用一些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

更多的争论可以看到与人树。


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

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

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

1.——回声。

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

将被扩展(由shell)以回显PWD中的所有目录。


要测试这一点:创建一个名为test-dir的目录(mkdir),并将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/

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


如果我们用ls代替echo。shell仍然是扩展文件名列表的对象。shell是获取PWD中的目录列表的原因。ls的-d选项使其列出当前目录条目,而不是每个目录的内容(默认情况下是这样)。

ls -d */

然而,这个命令(有点)不太可靠。对于上面列出的奇数命名文件,它将失败。它会因为几个名字而窒息。你需要一个一个地删除,直到找到有问题的。

2.-ls

GNU ls将接受“结束选项”(——)键。

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

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


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

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

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

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

Or

find -maxdepth 1 -type d | awk -F"./" '{print $2}'

供您参考,如果您想以多行打印所有文件,您可以执行ls -1,这将以单独的行打印每个文件。 file1 file2 file3


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

alias lsd='ls -ld */'

然后lsd会产生想要的结果。


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

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

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

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

\ls -d */

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

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

不包括符号链接

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

ls -l | grep '^d'

(可能通过sed或awk管道来隔离文件名)

包括符号链接

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

ls -1p | grep '/$'

或者,去掉后面的斜杠:

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

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

注意:如果我们想要后面的斜杠,但不希望它们被grep高亮显示,我们可以通过将实际匹配的部分设为空来删除高亮显示:

ls -1p | grep -P '(?=/$)'

使用Test -d测试项目是否为目录:

for i in $(ls); do test -d $i && echo $i ; done

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

使用Perl:

ls | perl -nle 'print if -d;'

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

ls -ltr | grep drw

仅列出目录:

ls -l | grep ^d

只列出文件:

ls -l | grep -v ^d 

或者你也可以这样做:

ls -ld */

下面是我只列出目录名的方法:

ls -1d /some/folder/*/ | awk -F "/" "{print \$(NF-1)}"

回答最初的问题,*/和ls本身没有关系;它是由shell/Bash完成的,这个过程被称为globbing。

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


一个当前目录的普通列表,它将是:

ls -1d */

如果你想要整理干净:

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

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


这里是一个使用树的变种,它只在单独的行上输出目录名,是的,它很丑,但是,嘿,它工作。

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

或者用awk

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

然而,这可能更好,并且将保留目录名之后的/。

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

如果你有空间在你的文件夹名称$9打印不工作尝试下面的命令

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

输出

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

Ls和awk(不含grep)

No need to use grep since awk can perform regularexpressino check so it is enough to do this:

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

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

非常简单明了


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

find * -maxdepth 0 -type d

不同之处在于它在开始时没有./,并且文件夹名称可以随时使用。