for d in *; do
echo $d
done
将循环浏览所有文件,但是我只想循环浏览目录。我该怎么办?
#1 楼
您可以在末尾指定一个斜杠以仅匹配目录:for d in */ ; do
echo "$d"
done
#2 楼
您可以使用-d
进行测试: for f in *; do
if [ -d "$f" ]; then
# $f is a directory
fi
done
这是文件测试运算符之一。 br />
评论
请注意,它将包括指向目录的符号链接。
–StéphaneChazelas
13年8月14日在16:12
如果[[-d“ $ f” &&! -L“ $ f”]]将排除符号链接
–rubo77
13-10-22在6:33
将在空目录上中断。如果[[“ $ f” =“ *”]];然后继续;科幻
– Piskvor离开了建筑物
19年4月1日在9:02
#3 楼
要注意的是,如果当前目录中没有可用目录,那么choroba的解决方案虽然很优雅,但却会引起意外的行为。在这种状态下,bash不会跳过for
循环,而是会在d
等于*/
的情况下仅运行一次循环:#!/usr/bin/env bash
for d in */; do
# Will print */ if no directories are available
echo "$d"
done
我建议使用以下内容来防止在这种情况下:此代码将循环遍历当前目录中的所有文件,检查
f
是否为目录,然后在条件返回true时回显f
。如果f
等于*/
,则不会执行echo "$f"
。评论
购物-s nullglob要容易得多。
–乔罗巴
16年6月23日在7:14
#4 楼
如果您需要选择的文件比仅目录更多,请使用find
并将其传递给while read
:shopt -s dotglob
find * -prune -type d | while IFS= read -r d; do
echo "$d"
done
使用
shopt -u dotglob
排除隐藏目录(或zsh中的setopt dotglob
/ unsetopt dotglob
) 。IFS=
避免拆分包含$IFS
之一的文件名,例如:'a b'
有关更多
find
选项,请参见下面的AsymLabs答案编辑:
如果需要从while循环中创建退出值,则可以通过以下技巧绕开多余的子外壳:
while IFS= read -r d; do
if [ "$d" == "something" ]; then exit 1; fi
done < <(find * -prune -type d)
评论
我在以下位置找到了此解决方案:stackoverflow.com/a/8489394/1069083
–rubo77
13-10-22在5:06
#5 楼
您可以为此使用纯bash,但最好使用find:find . -maxdepth 1 -type d -exec echo {} \;
(另外查找会包含隐藏目录)
评论
请注意,它不包含指向目录的符号链接。您可以将shopt -s dotglob用于bash来包含隐藏目录。您还将包括..还应注意,-maxdepth不是标准选项(-prune是)。
–StéphaneChazelas
13年8月14日在16:11
dotglob选项很有趣,但是dotglob仅适用于*。找 。将始终包含隐藏目录(以及当前目录)
–rubo77
13-10-22在5:28
#6 楼
这样做是为了在当前工作目录中查找可见目录和隐藏目录,而不是查找根目录:循环浏览目录:
find -path './*' -prune -type d
在结果中包括符号链接:
find -L -path './*' -prune -type d
对每个目录进行某些操作(不包括符号链接):
find -path './*' -prune -type d -print0 | xargs -0 <cmds>
排除隐藏目录:
find -path './[^.]*' -prune -type d
对返回的值执行多个命令(非常人为的示例):
find -path './[^.]*' -prune -type d -print0 | xargs -0 -I '{}' sh -c \
"printf 'first: %-40s' '{}'; printf 'second: %s\n' '{}'"
代替'sh -c'也可以使用'bash -c'等。
评论
如果回显* /中的for d中的回显'* /'包含60,000个目录,会发生什么情况?
– AsymLabs
13-10-21在4:05
您将收到“ Too many files”错误,但可以解决:如何在debian中规避“ Too many open files”
–rubo77
13-10-21在4:09
xargs示例仅适用于目录名称9e.g的子集。那些带有空格或换行符的行将无效)。更好地使用... -print0 | xargs -0 ...如果您不知道确切名称是什么。
–安东
13-10-21在4:50
@ rubo77添加了排除隐藏文件/目录和执行多个命令的方法-当然,这也可以通过脚本来完成。
– AsymLabs
13-10-21在11:22
我在底部的答案中添加了一个示例,该示例如何使用带有find * |的函数对每个目录执行操作在读取文件时;做...
–rubo77
13-10-22在4:37
#7 楼
您可以在一行中循环浏览所有目录,包括隐藏目录(以点开头)和使用以下命令的多个命令:for file in */ .*/ ; do echo "$file is a directory"; done
如果要排除符号链接:
for file in *; do
if [[ -d "$file" && ! -L "$file" ]]; then
echo "$file is a directory";
fi;
done
注意:使用列表
*/ .*/
在bash中有效,但也显示文件夹.
和..
,而在zsh中则不会显示这些文件夹,但如果存在则抛出错误文件夹中没有隐藏文件更干净的版本将包含隐藏目录并排除../,将带有dotglob选项:
shopt -s dotglob
for file in */ ; do echo "$file is a directory"; done
(或zsh中的
setopt dotglob
)您可以使用
shopt -u dotglob
取消设置dotglob
#8 楼
这将包括列表中每个目录中的完整路径:for i in $(find $PWD -maxdepth 1 -type d); do echo $i; done
评论
使用带空格的文件夹时会中断
–亚历杭德罗·萨佐(Alejandro Sazo)
16-10-24在2:15
#9 楼
使用find
和-exec
循环浏览目录并在exec选项中调用函数:dosomething () {
echo "doing something with "
}
export -f dosomething
find -path './*' -prune -type d -exec bash -c 'dosomething "q4312078q"' {} \;
使用
shopt -s dotglob
或shopt -u dotglob
包括/排除隐藏目录#10 楼
这列出了给定路径中的所有目录以及子目录的数量:for directory in */ ; do D=$(readlink -f "$directory") ; echo $D = $(find "$D" -mindepth 1 -type d | wc -l) ; done
#11 楼
ls -d */ | while read d
do
echo $d
done
评论
这是一个名称中带有空格的目录-但会被解析为多个。
– Piskvor离开了建筑物
19-3-28在11:35
#12 楼
ls -l | grep ^d
或:
ll | grep ^d
您可以将其设置为别名
评论
不幸的是,我认为这不能回答这个问题,即“我只想遍历目录”,这与基于ls的列出目录的回答略有不同。
– Jeff Schaller♦
17年9月11日在20:26
解析ls的输出绝不是一个好主意:mywiki.wooledge.org/ParsingLs
– codeforester
18年8月21日在18:38
评论
请注意,它还包括指向目录的符号链接。
–StéphaneChazelas
13年8月14日在16:09
那么您如何排除符号链接?
–rubo77
13年8月14日在22:55
@ rubo77:您可以使用[[-L $ d]]测试$ d是否是符号链接。
–乔罗巴
13年8月14日在23:00
@choroba:在这种情况下,[[-L“ $ f”]]不会排除符号链接,您必须使用[[-L“ $ {f%/}”]]去除斜杠(请参见测试与斜杠链接)
–rubo77
13-10-23在6:54
@timbram:*是通配符,表示“任何”。 /表示“任何内容”必须是目录才能匹配通配符表达式。 ;是for循环的一部分,它将do与for分开。
–乔罗巴
17年7月28日在16:11