array=${ls -d */}
echo ${array[@]}
我有三个目录:ww
ee
qq
。我希望它们在数组中,然后打印该数组。
Answers:
就是这个
array=($(ls -d */))
编辑:请参阅戈登·戴维森(Gordon Davisson)的解决方案,以获得更一般的答案(即,如果文件名包含特殊字符)。这个答案仅仅是语法校正。
ARR+=('$(ls -d */)')
来编辑数组中的元素,同时使用单引号处理特殊字符,以在其中添加或删除元素数组。单引号保留字面字符,并消除了在目录名称中使用转义符进行处理的任何需要。
declare -a ARR; ARR+=('$(ls -d "$INPUT_DIR"/*)')
仅返回$(ls -d $INPUT_DIR/*)
ARR+=("$(ls -d */)")
应该管用。如果不是,就让我知道。
只要有可能,就应该避免解析输出ls
(请参阅Greg关于该主题的Wiki)。基本上,ls
如果任何文件名中都有有趣的字符,的输出将是模糊的。通常也浪费时间。在这种情况下,执行时ls -d */
,shell将扩展*/
为一个子目录列表(这已经完全是您想要的),并将该列表作为参数传递给ls -d
,然后对每个子目录进行查看,并说“是的,那是一个目录正确”并打印出来(格式不一致,有时甚至模棱两可)。该ls
命令没有做任何有用的事情!
好吧,这是一件有用的事情:如果没有子目录,那么*/
将保留原样,ls
将查找名为“ *”的子目录,找不到它,并打印一条不存在的错误消息( stderr),而不打印“ * /”(至stdout)。
创建子目录名称数组的更干净的方法是使用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
/
dir名称怎么办?
ls
是一个简单的命令。它的输出是字符串。Bash在解析字符串方面非常擅长。正确的正则表达式是安全解析ls
输出所必需的。
ls
文件名使用文件名中的有趣/非打印字符来执行不同的操作,因此没有一致的方法将其输出解析为文件名列表。就像我说的,它实际上并没有做任何有用的事情:如果您正确解析的输出ls -d */
,那么最终会得到与您直接从中得到的完全一样的东西*/
(除非没有匹配项,并且很容易检查)。
A lazy sysadmin is a good sysadmin.
也许我自己的ls
解析特定于我所拥有的版本,或者我曾经使用过,但是到目前为止,它们在我对其进行测试的linux发行版上都没有问题。我只能凭经验说话。
这将逐行打印这些目录中的文件。
array=(ww/* ee/* qq/*)
printf "%s\n" "${array[@]}"