【问题标题】:Looping through an array and appending a variable with the results循环遍历数组并将结果附加到变量中
【发布时间】:2019-08-20 02:02:28
【问题描述】:

我编写了一个小型 bash 脚本,用于搜索文件夹、提取不符合特定条件的文件列表并将它们分配给数组。然后我循环遍历该数组并将内容输出到标准输出。我想要做的是将这些结果中的每一个附加到一个变量中,然后我想稍后在代码中使用它。我正在努力寻找有关如何执行此操作的任何信息。看起来它应该超级简单,相当于回声附加类型的东西,但我在网上找到了零个例子。我想要类似的东西:$list = $list + $addition

这是我目前所拥有的。最后一块已经完成了 95%。

    #Declare the array
    array=()

    #Search for any files that are not mp4's. Exclude temp files also.
    while IFS=  read -r -d $'\0'; do
      array+=("$REPLY")
        done < <(find "$movies_dir" -type f -not -name "*.mp4" -not -name "*.srt" -not -name "*.db" -not -name "*.tmp" -not -name "*DS_Store" -not -name "._*" -print0)

    #Create an empty variable to assign the list of movies to
    movie_list=""

    # Loop through array pulling out each movie found    
    if [ ${#array[@]} -gt 0 ]; then
      for i in "${array[@]}"
        do
          movie="${i##*/}"
          echo -n "$movie\n"
        done
    fi

从上面的代码可以看出,这会将所有电影输出为一个长字符串,用 \n 分隔每个文件名(我计划稍后在 Slack 警报中使用)。考虑到这一点,这就是我需要将文本字符串分配给变量的原因。我希望能够在我的 Slack 通知中使用它。

谁能指出我如何实现上述目标?

谢谢。

【问题讨论】:

  • 您是在问如何将命令的输出放入变量中?您可以使用var=$(your command here)。该命令可以是for 循环。
  • list+=" $addition" 听起来像你想要的(将" $addition" 连接到list 的末尾,直到你用完添加 - 但请注意,list 将是一个字符串,为什么不让它成为一个单独的数组?)

标签: bash loops variables


【解决方案1】:

我不完全确定我理解了这个问题(以及为什么这很困难)。通常,您可以使用var+=addition 附加到字符串变量。在这种情况下,唯一棘手的事情是您要附加一个变量 一个换行符,而对于相同的引用模式(变量周围的双引号和 ANSI 模式 @ 987654322@ 换行)。但是你可以在一个字符串中混合引用模式,所以这样的东西应该可以工作:

movie_list=""
for i in "${array[@]}"; do
      movie_list+="${i##*/}"$'\n'
done

(请注意,不需要if,因为如果数组为空,则循环根本不会运行。)

还有其他方法可以避免显式循环,例如使用 printf-v 选项(输出到变量):

if [ ${#array[@]} -gt 0 ]; then
    printf -v movie_list '%s\n' "${array[@]##*/}"
else
    movie_list=""
fi

(这里,请注意[@]##*/ 扩展到数组的所有元素,而*/每个元素中单独删除。)

或者您可以使用数组的[*] 扩展,它将数组的所有元素混合在一起,由IFS 的第一个字符分隔,您可以将其更改为换行符:

saveIFS="$IFS"
IFS=$'\n'
movie_list="${array[*]##*/}"
IFS=$saveIFS

与这个不同的是,它不会在末尾添加换行符,而是在元素之间添加换行符。但是如果你使用echo 来打印它,那将在最后附加它自己的换行符。

【讨论】:

  • 是的,所以我不确定为什么那个解决方案当时不明显(尝试在凌晨 2 点编写代码可能没有帮助)。事实是,我的 bash 脚本经验在很大程度上是一项正在进行的工作。不过,这个解决方案起到了作用,感谢您花时间编写它。
【解决方案2】:

如果你想打印一个换行分隔的文件列表,这可以完全由find处理:

find \
  "$movies_dir" \
  -type f \
  -regextype egrep \
  -not -iregex '.*\.(mp4|srt|db|tmp|_.*|DS_Store)$' \
  -printf '%f\n'

【讨论】:

    猜你喜欢
    • 2021-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-04
    • 2021-11-02
    • 1970-01-01
    • 2012-07-02
    • 1970-01-01
    相关资源
    最近更新 更多