Arrays 在LinuxBash中,如何将ls分配给数组?

Arrays 在LinuxBash中,如何将ls分配给数组?,arrays,bash,shell,ls,Arrays,Bash,Shell,Ls,我有三个目录:wweeqq。我希望它们在一个数组中,然后打印数组。就是这样 array=${ls -d */} echo ${array[@]} 编辑:请参阅以获得更一般的答案(即,如果文件名包含特殊字符)。这个答案只是一个语法更正。这将逐行打印这些目录中的文件 array=($(ls -d */)) 只要有可能,您应该避免解析ls(请参阅)的输出。基本上,如果任何文件名中有有趣的字符,ls的输出将是不明确的。这通常也是浪费时间。在本例中,当您执行ls-d*/时,发生的情况是shell将

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

就是这样

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

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

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

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

只要有可能,您应该避免解析
ls
(请参阅)的输出。基本上,如果任何文件名中有有趣的字符,
ls
的输出将是不明确的。这通常也是浪费时间。在本例中,当您执行
ls-d*/
时,发生的情况是shell将
*/
扩展到一个子目录列表(这已经是您想要的),将该列表作为参数传递给
ls-d
,该列表查看每个目录,并显示“是的,这是一个正确的目录”,然后打印它(格式不一致,有时模棱两可)。ls命令没有任何用处

好的,好的,它正在做一件有用的事情:如果没有子目录,
*/
将保持不变,
ls
将查找名为“*”的子目录,但找不到它,打印一条不存在的错误消息(到stderr),而不是打印“*/”(到stdout)

生成子目录名称数组的更简洁的方法是使用glob(
*/
),而不将其传递给
ls
。但是为了避免在没有实际子目录的情况下将“*/”放入数组,您应该先设置nullglob(再次请参见):

如果要在没有子目录的情况下打印错误消息,最好自己打印:

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

感谢您的评论,尽管没有标记为答案,但它提供了大量的信息,我对此表示感谢。如果您不希望目录名中包含
/
,该怎么办?greg的wiki中概述的问题/问题并不是单凭条件构造无法轻松解决的。
ls
是一个简单的命令。它的输出是strings.Bash非常擅长解析字符串。正确的正则表达式是安全解析
ls
输出所必需的一切。@Yokai不同版本的
ls
在文件名中使用有趣/非打印字符做不同的事情,因此没有一致的方法将其输出解析为文件名列表。正如我所说的,它不是actually做任何有用的事情:如果您正确地解析了
ls-d*/
的输出,那么您得到的结果与直接从
*/
得到的结果完全相同(除非没有匹配项,而且很容易检查)因此,总而言之:
一个懒惰的系统管理员是一个好的系统管理员。
也许我自己的
ls
解析特定于我拥有的版本,或者我已经习惯的版本,但是到目前为止,在我测试过的linux发行版上,他们没有任何问题。我只能凭经验说话。如果目录名包含空格,这将无法正常工作。按顺序r要解决空格或特殊字符的问题,请先声明不带任何值的数组,然后使用内置的
ARR+=('$(ls-d*/)'))
用于编辑数组中的元素,同时使用单引号处理特殊字符,以向该数组添加或删除元素。单引号保留了文字字符,并且不需要在目录名中转义处理它们。@Yokai你的建议听起来很好,但在Ubuntu 16.04或MacOs上对我不起作用.Bash在单引号之间展开代码,如下所示:
declare-a ARR;ARR+=('$(ls-d“$INPUT\u DIR”/*)
仅返回
$(ls-d$INPUT\u DIR/*)
我的错误。这应该是双引号,以便可以展开命令替换。
ARR+=(“$(ls-d*/))
应该可以。如果不让我知道的话。@Yokai,这只会添加一个元素总数(其中有一堆换行符),而不是每个目录添加一个元素。这回答了你的问题吗?
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