修改bash数组中的元素

时间:2016-08-27 21:23:50

标签: arrays bash loops for-loop epoch

我有一个数组${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仅包含上次的纪元值

echo ${epochtimearray[*]}
1472331840

有没有人看到我在这里缺少的东西,或者有更好的方法来减去时间。

3 个答案:

答案 0 :(得分:2)

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

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

或将元素设置为给定索引:

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

答案 1 :(得分:0)

这种情况多次出现 - 我不建议将其用于大量值,但它肯定比在循环中运行日期更好

# 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

答案 2 :(得分:0)

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

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-)分隔的垂直列,然后将生成的行(看起来很像减法:)提供给计算器{ {1}},用于计算每一行的值。