我在Linux上用bash编写脚本,需要遍历给定目录中的所有子目录名称。如何遍历这些目录(并跳过常规文件)?
例如:
给定目录为/tmp/
它有以下子目录:/tmp/A, /tmp/B, /tmp/C
我想要检索A,B,C。
答案 0 :(得分:385)
到目前为止,所有答案都使用find
,所以这里只有shell。在您的情况下无需外部工具:
for dir in /tmp/*/ # list directories in the form "/tmp/dirname/"
do
dir=${dir%*/} # remove the trailing "/"
echo ${dir##*/} # print everything after the final "/"
done
答案 1 :(得分:116)
cd /tmp
find . -maxdepth 1 -mindepth 1 -type d -printf '%f\n'
一个简短的解释:find
找到文件(很明显)
。是当前目录,在cd之后它是/tmp
(恕我直言,这比直接在查找命令中/tmp
更灵活。你只有一个地方,cd
,要改变,如果您希望在此文件夹中执行更多操作)
-maxdepth 1
和-mindepth 1
确保find
确实只查看当前目录,并且结果中不包含“.
” / p>
-type d
仅查找目录
-printf '%f\n
仅为每次点击打印找到的文件夹名称(加上换行符)。
答案 2 :(得分:38)
您可以使用以下命令遍历所有目录,包括隐藏的目录(以点开头):
for file in */ .*/ ; do echo "$file is a directory"; done
注意:只有在文件夹中至少存在一个隐藏目录时,使用列表*/ .*/
才能在zsh中运行。在bash中,它还会显示.
和..
bash包含隐藏目录的另一种可能性是使用:
shopt -s dotglob;
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
要在每个解决方案中仅输出尾随目录名称(A,B,C作为疑问),请在循环中使用它:
file="${file%/}" # strip trailing slash
file="${file##*/}" # strip path and leading slash
echo "$file is the directoryname without slashes"
mkdir /tmp/A /tmp/B /tmp/C "/tmp/ dir with spaces"
for file in /tmp/*/ ; do file="${file%/}"; echo "${file##*/}"; done
答案 3 :(得分:14)
受Sorpigal启发
while IFS= read -d $'\0' -r file ; do
echo $file; ls $file ;
done < <(find /path/to/dir/ -mindepth 1 -maxdepth 1 -type d -print0)
受Boldewyn启发:带find
命令的循环示例。
for D in $(find /path/to/dir/ -mindepth 1 -maxdepth 1 -type d) ; do
echo $D ;
done
答案 4 :(得分:7)
find . -mindepth 1 -maxdepth 1 -type d -printf "%P\n"
答案 5 :(得分:5)
我最常使用的技术是find | xargs
。例如,如果要使此目录中的每个文件及其所有子目录都具有全局可读性,则可以执行以下操作:
find . -type f -print0 | xargs -0 chmod go+r
find . -type d -print0 | xargs -0 chmod go+rx
-print0
选项以NULL字符而不是空格终止。 -0
选项以相同的方式拆分其输入。所以这是在带空格的文件上使用的组合。
您可以将此命令链描绘为将find
的每一行输出并将其粘贴在chmod
命令的末尾。
如果要在中间而不是在结尾处运行作为参数的命令,则必须有点创意。例如,我需要更改到每个子目录并运行命令latemk -c
。所以我用(来自Wikipedia):
find . -type d -depth 1 -print0 | \
xargs -0 sh -c 'for dir; do pushd "$dir" && latexmk -c && popd; done' fnord
这具有for dir $(subdirs); do stuff; done
的效果,但对于名称中包含空格的目录是安全的。此外,对stuff
的单独调用是在同一个shell中进行的,这就是为什么在我的命令中我们必须返回到popd
的当前目录。
答案 6 :(得分:2)
find . -type d -maxdepth 1
答案 7 :(得分:2)
你可以构建的最小bash循环(基于ghostdog74回答)
for dir in directory/*
do
echo ${dir}
done
按目录
压缩一大堆文件for dir in directory/*
do
zip -r ${dir##*/} ${dir}
done
答案 8 :(得分:0)
如果要在for循环中执行多个命令,则可以将find
的结果与mapfile
(bash> = 4)保存为变量,并使用{{1 }}。它也可以用于包含空格的目录。
${dirlist[@]}
命令基于Boldewyn的answer。可以在此处找到有关find
命令的更多信息。
find