修改 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
,计算每一行的值。
我有一个数组${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
,计算每一行的值。