102
array=${ls -d */}
echo ${array[@]}  

我有三个目录:ww ee qq. 我希望它们在一个数组中,然后打印该数组。

4

3 回答 3

134

会是这样

array=($(ls -d */))

编辑:请参阅Gordon Davisson 的解决方案以获得更一般的答案(即,如果您的文件名包含特殊字符)。这个答案只是一个语法更正。

于 2013-09-19T01:49:37.697 回答
92

只要有可能,您应该避免解析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
于 2013-09-19T06:05:01.827 回答
11

这将逐行打印这些目录中的文件。

array=(ww/* ee/* qq/*)
printf "%s\n" "${array[@]}"
于 2013-09-19T02:01:41.560 回答