【问题标题】:How can I store a list of directories in an array?如何将目录列表存储在数组中?
【发布时间】:2012-07-20 00:09:16
【问题描述】:

为什么这没有列出任何东西?谢谢

FOLDER=()

ls /tmp/backup/ | while read DIR
do
    FOLDER+=("$DIR")
done

echo ${FOLDER[1]}

【问题讨论】:

    标签: arrays bash directory


    【解决方案1】:

    分析

    您的示例旨在失败。例如:

    • 不要解析ls的输出。
    • 不要假设目录中的每个条目都是目录。
    • 不要在没有充分理由的情况下在循环中追加数组。
    • 不要使用未加引号的变量。

    使用 Shell Glob

    假设 /tmp/backup 中的每个条目都是一个目录,您可以简单地使用 shell glob 来填充您的数组。如果您可能有文件和目录条目,那么您需要使用 find 或使用 shell 测试表达式来确保该条目实际上是一个目录。例如:

    # Enable special handling to prevent expansion to a
    # literal '/tmp/backup/*' when no matches are found. 
    shopt -s nullglob
    
    FOLDERS=(/tmp/backup/*)
    for folder in "${FOLDERS[@]}"; do
        [[ -d "$folder" ]] && echo "$folder"
    done
    
    # Unset shell option after use, if desired. Nullglob
    # is unset by default.
    shopt -u nullglob
    

    【讨论】:

    • 打开nullglob 选项可能是个好主意,这样如果目录为空,就不会按字面意思处理glob。
    • 不要调用目录文件夹! ;-)
    • 这是分析列表的另一个项目符号。
    • @MichaelKrelin-hacker 这只是为了保留 OP 的语义。您可以随心所欲地调用该变量,但您的观点是正确的。
    • @CodeGnome,这就是我添加第二条评论的原因——这并不是对您的答案的更正,而是对您的缺陷列表的补充;)
    【解决方案2】:

    要解决 subshel​​lissue(请参阅 Diego 的回答),您还可以执行类似的操作

    while ....
    done <<<$(ls)
    

    【讨论】:

    • 这是处理文件名中范围和可能的空格的正确方法。
    • @Raphink,空间处理取决于while 中的内容。我会推荐IFS= read f 或类似的
    • 默认情况下,while 使用换行符作为 IFS,而for 使用空格,因此我的评论。
    • while 没有IFS 的概念,但是是的,如果只提供一个,read 会将所有内容都放入变量中。我不记得在哪种情况下您需要将IFS= 指定为read。也许一些古代版本需要那个……
    • @DennisWilliamson,不解析ls 输出的想法是一个很好的想法,尽管 OP 遇到的问题不是由于解析,所以我认为解决这个直接问题很重要。
    【解决方案3】:

    while 在子 shell 中执行,它不能修改父 shell 的变量,在本例中为 FOLDER。你应该尝试其他方法。例如:

    FOLDER=(`ls /tmp/backup`)
    echo ${FOLDER[1]}
    

    (将在那里打印第二个文件)

    注意:是的,我理解这个解决方案的问题,空格,ls 的使用等。我只是想指出while 的问题。要完成答案,是的,应该使用通配符:

    for dir in /tmp/backup/* ; do
        test -d "$dir" && do_stuff_with_dir("$dir")
    done
    

    而且,由于不死于纯粹主义,通常(至少在 UNIX 中)在文件名中包含空格。这对你的健康有害:)

    【讨论】:

    • FOLDER 在此分配后不会变成数组。 echo 将再次为空。但是 subshel​​l 是正确的。
    • (我编辑了帖子以使FOLDER 成为一个数组;我还没有看到@nshy 的评论)。
    • @chepner 然后在文件名中出现空格
    • 许多文件的名称中都有空格。 ls 不应该以这种方式使用。应改为使用 glob。使用 for 循环对 glob 进行迭代消除了对管道的需求,因此不会创建子外壳。
    • @DennisWilliamson,你当然是对的......只是开玩笑。我更新了我的回复。
    【解决方案4】:

    正如其他人已经提到的,上面代码的问题之一是修改子shell中的变量。另一种是使用+= 来填充数组。不幸的是,这只是作为字符串添加到第零个元素,因此FOLDERS[1] 保持未定义。

    【讨论】:

    • array+=(element) 不会作为字符串添加到第零个元素 - 它会将新元素附加到数组中。
    • 这是狂欢!请注意——我错过了括号。 @DennisWilliamson 谢谢
    猜你喜欢
    • 2012-04-14
    • 1970-01-01
    • 2010-10-24
    • 2021-08-27
    • 2021-01-28
    • 1970-01-01
    • 2019-12-21
    • 2021-09-19
    • 1970-01-01
    相关资源
    最近更新 更多