【发布时间】:2012-12-30 09:51:27
【问题描述】:
此命令列出当前路径中的目录:ls -d */
*/ 模式究竟做了什么?
我们如何在上述命令中给出绝对路径(例如ls -d /home/alice/Documents),以便仅列出该路径中的目录?
【问题讨论】:
此命令列出当前路径中的目录:ls -d */
*/ 模式究竟做了什么?
我们如何在上述命令中给出绝对路径(例如ls -d /home/alice/Documents),以便仅列出该路径中的目录?
【问题讨论】:
*/ 是匹配当前目录中所有子目录的模式(* 将匹配所有文件 和 子目录;/ 将其限制为目录)。同样,要列出 /home/alice/Documents 下的所有子目录,请使用 ls -d /home/alice/Documents/*/
【讨论】:
*/ 不会匹配任何隐藏文件夹。要包含它们,可以像 ls -d .*/ */ 或 Bash 中的 set the dotglob option 那样明确指定它们。
shopt -s nullglob
ls */ 将扩展为仅 ls,这将列出所有文件当前目录。在这种情况下,我很确定这不是您想要的。
*/ 还设置子目录的名称以斜杠结尾。
./ ../: ls -d */ .[^.]*/
echo
示例:echo */、echo */*/
这是我得到的:
cs/ draft/ files/ hacks/ masters/ static/
cs/code/ files/images/ static/images/ static/stylesheets/
ls
示例:ls -d */
这正是我得到的:
cs/ files/ masters/
draft/ hacks/ static/
或作为列表(带有详细信息):ls -dl */
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
示例: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/
【讨论】:
3 对我来说明显比其他人慢。在我测试的目录中:1.012s,2.016s,3.055s,4.021s.
1是我的最爱。
time,Unix 函数。 /// 我同意,echo */ 比 ls -d */ 聪明。
1. 选项在处理包含空格的文件夹名称时会带来很大的麻烦。
我用:
ls -d */ | cut -f1 -d'/'
这会创建一个不带斜杠的单列 - 在脚本中很有用。
【讨论】:
ls 的-1 选项也将以单列格式输出,如ls -1 -d */。
-1 仍然为每个条目输出一个斜杠。
.bashrc 作为别名时,如何添加'/'?
'\/'
| sed -e 's-/$--'
对于所有没有子文件夹的文件夹:
find /home/alice/Documents -maxdepth 1 -type d
对于所有带有子文件夹的文件夹:
find /home/alice/Documents -type d
【讨论】:
find /home/alice/Documents -maxdepth 1 -mindepth 1 -type d 否则你包括 /home/alice/Documents 本身。要包含指向目录的符号链接,请以 -L 为前缀
未引用星号* 将被shell 解释为模式(glob)。 shell 将在路径名扩展中使用它。然后它将生成与该模式匹配的文件名列表。
一个简单的星号将匹配 PWD(当前工作目录)中的所有文件名。像*/ 这样更复杂的模式将匹配所有以/ 结尾的文件名。因此,所有目录。这就是为什么命令:
echo */
echo ./*/ ### Avoid misinterpreting filenames like "-e dir"
将(通过 shell)扩展为 echo 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/
但是文件名中的空格使阅读有点混乱。
如果不是echo,我们使用ls。外壳仍然是扩展文件名列表的东西。 shell 是在 PWD 中获取目录列表的原因。 ls 的 -d 选项使其列出当前目录条目,而不是每个目录的内容(默认显示)。
ls -d */
但是,这个命令(有点)不太可靠。它会因上面列出的奇怪的命名文件而失败。它会被几个名字窒息。你需要一个一个地擦除,直到找到有问题的。
GNU ls 将接受“选项结束”(--) 键。
ls -d ./*/ ### More reliable BSD ls
ls -d -- */ ### More reliable GNU ls
要在单独的行中列出每个目录(在一列中,类似于 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)。最后,在函数内部使用参数列表不会影响当前运行的 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 树,并使用当前目录的完整路径,您可以这样做:
$ 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查看。
【讨论】:
如果您想知道为什么 '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 '(?=/$)'
【讨论】:
当前目录的简单列表,它是:
ls -1d */
如果你想要它排序和清洁:
ls -1d */ | cut -c 1- | rev | cut -c 2- | rev | sort
记住:大写字符在排序中具有不同的行为
【讨论】:
如果不需要列出隐藏目录,我提供:
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}'
【讨论】:
awk的信息,请查看此answer
ls -l | awk '/^d/ {print $9}' 有效,没有目录时其他方案无效
我只是将它添加到我的.bashrc 文件中(如果您只需要/想要一个会话,您也可以在命令行中键入它):
alias lsd='ls -ld */'
然后lsd会产生想要的结果。
【讨论】:
仅列出目录:
ls -l | grep ^d
仅列出文件:
ls -l | grep -v ^d
或者你也可以这样做:
ls -ld */
【讨论】:
显示没有/的文件夹列表:
ls -d */|sed 's|[/]||g'
【讨论】:
ls -d1 */ | tr -d "/"
set -- */; printf "%s\n" "${@%/}"
试试这个。它适用于所有 Linux 发行版。
ls -ltr | grep drw
【讨论】:
ls -l | grep '^d' | awk '{print $9}'
这是我正在使用的
ls -d1 /Directory/Path/*;
【讨论】:
ls -d1 /Directory/Path/*/
测试item是否为test -d的目录:
for i in $(ls); do test -d $i && echo $i ; done
【讨论】:
仅供参考,如果您想多行打印所有文件,您可以使用ls -1 将每个文件打印在单独的行中。
文件 1
文件2
文件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'
}
【讨论】:
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
【讨论】:
ls -l | awk '/^d/ {print $9}'
ls -l 列出具有权限的文件 awk 过滤输出 '/^d/' 正则表达式仅搜索以字母 d 开头的行(作为目录)查看第一行 - 权限 {print} 将打印所有列{print $9} 将仅打印来自 ls -l 的 第 9 列(名称)输出
非常简单干净
【讨论】:
仅从“这里”列出目录。
有文件数。
for i in `ls -d */`; do g=`find ./$i -type f -print| wc -l`; echo "Directory $i contains $g files."; done
【讨论】:
使用 Perl:
ls | perl -nle 'print if -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
嗯,这对我来说是主要部分:)
【讨论】:
这是一个使用 tree 的变体,它只在单独的行上输出目录名称,是的,它很丑,但是嘿,它可以工作。
tree -d | grep -E '^[├|└]' | cut -d ' ' -f2
或使用 awk
tree -d | grep -E '^[├|└]' | awk '{print $2}'
这可能会更好,但会在目录名称后保留/。
ls -l | awk '/^d/{print $9}'
【讨论】:
回答原问题,*/与ls本身无关;它是由 shell/Bash 在称为 globbing 的过程中完成的。
这就是echo */ 和ls -d */ 输出相同元素的原因。 (-d 标志使ls 输出目录名称而不是目录内容。)
【讨论】:
添加以使其完整循环,检索每个文件夹的路径,使用 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 -1d /some/folder/*/ | awk -F "/" "{print \$(NF-1)}"
【讨论】:
如果您的文件夹名称中有空间 $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
【讨论】: