array=${ls -d */}
echo ${array[@]}
我有三个目录:ww
ee
qq
. 我希望它们在一个数组中,然后打印该数组。
只要有可能,您应该避免解析ls
(参见Greg 的关于该主题的 wiki)的输出。基本上,ls
如果任何文件名中有有趣的字符, 的输出将是模棱两可的。这通常也是浪费时间。在这种情况下,当您执行 时ls -d */
,会发生外壳扩展*/
为子目录列表(这正是您想要的),将该列表作为参数传递给ls -d
,它查看每个子目录,说“是的,那是一个目录好吧”并打印出来(格式不一致,有时模棱两可)。该ls
命令没有做任何有用的事情!
好吧,它正在做一件有用的事情:如果没有子目录,*/
将保持原样,ls
将查找名为“*”的子目录,找不到它,打印一条错误消息它不存在(到stderr),而不是打印“*/”(到标准输出)。
创建子目录名称数组的更简洁的方法是使用 glob( */
)而不将其传递给ls
. 但是为了避免在没有实际子目录的情况下将“*/”放入数组中,您应该首先设置 nullglob(再次,请参阅Greg 的 wiki):
shopt -s nullglob
array=(*/)
shopt -u nullglob # Turn off nullglob to make sure it doesn't interfere with anything later
echo "${array[@]}" # Note double-quotes to avoid extra parsing of funny characters in filenames
如果你想在没有子目录的情况下打印错误消息,你最好自己做:
if (( ${#array[@]} == 0 )); then
echo "No subdirectories found" >&2
fi
这将逐行打印这些目录中的文件。
array=(ww/* ee/* qq/*)
printf "%s\n" "${array[@]}"