修改 bash 数组中的元素

Modifying elements in bash array

我有一个数组${timearray[*]},其中包含这种格式的次数

20:56 20:57 20:59 21:01 21:04

还有第二个数组${productarray[*]}包含不同的时间

20:54 20:56 20:58 21:00 21:02

我需要通过减去时间减去产品来获得两者之间的差异。为此,我认为我需要在减去之前将这些时间转换为纪元时间,然后除以 60 并四舍五入到最近的分钟。我尝试使用这样的 for 循环来进行转换。

arraylength=`expr ${#timearray[@]} -1`
for ((l=0; l<=$arraylength; l++))
do
    epochtimearray=(`date --date="${timearray[$l]}" +%s`)
done

然而生成的epochtimearray只包含最后一次的epoch值

echo ${epochtimearray[*]}
1472331840

有没有人看到我在这里遗漏了什么,或者有没有更好的方法来减去时间。

要向数组添加元素,请使用 += 运算符:

epochtimearray+=(`date --date="${timearray[$l]}" +%s`)

或在给定索引处设置元素:

epochtimearray[l]=(`date --date="${timearray[$l]}" +%s`)

这有很多不同之处 - 我不推荐它用于大量值,但它肯定比 运行 循环中的日期好

# populate couple arrays
declare -a timearray=(20:56 20:57 20:59 21:01 21:04)
declare -a productarray=(20:54 20:56 20:58 21:00 21:02)

# convert multiple times for today into epoch seconds
IFS=$'\n'
timeepochs=($(echo "${timearray[*]}"|date -f- +%s))
prodepochs=($(echo "${productarray[*]}"|date -f- +%s))
unset IFS
for ((i=0; i < ${#timeepochs[*]}; ++i)); do
  echo "$i: ${timearray[i]} - ${productarray[i]} = $((timeepochs[i] - prodepochs[i])) seconds"
done

循环遍历数组元素通常比尝试构造索引容易得多:

for d in "${timearray[@]}"; do
  epochtimearray+=($(date "$d" +%s))
done

但是如果您使用的是 Gnu grep(显然您是),则可以使用 -f 选项通过一次调用处理所有时间:

epochtimearray=($(date +%s -f-<<<"$(IFS=$'\n'; echo "${timearray[*]}")"))

但是您实际上并不需要构建临时数组;您可以使用几个标准的 Unix 实用程序将所有内容组合在一起:

paste -d- <(date +%s -f-<<<"$(IFS=$'\n'; echo "${timearray[*]}")") \
          <(date +%s -f-<<<"$(IFS=$'\n'; echo "${productarray[*]}")") |
bc

它使用 paste 将两个列表组合成两个用短划线分隔的垂直列 (-d-),然后将生成的行(看起来很像减法 :) )输入计算器bc,计算每一行的值。