thatsboot3101
thatsboot3101

Reputation: 3

Modifying elements in bash array

I have an array ${timearray[*]} that contains a number of times in this format

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

There is a second array ${productarray[*]} that contains different times

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

I need to get a difference between the two by subtracting time minus product. To do this I believe I need to convert these times into epoch time before subtracting, I'll then divide by 60 and round to the nearest minute. I attempted using a for loop like this to do the conversion.

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

However the resulting epochtimearray only contains the epoch value of the last time

echo ${epochtimearray[*]}
1472331840

Does anyone see what I'm missing here or is there a better way to subtract time times.

Upvotes: 0

Views: 69

Answers (3)

rici
rici

Reputation: 241861

It is usually much easier to loop over array elements than to try to construct the indices:

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

But if you are using Gnu grep (which apparently you are), you can use the -f option to process all the times with a single call:

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

But you don't actually need to construct the temporary arrays; you can put the whole thing together using a couple of standard Unix utilities:

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

That uses paste to combine the two lists into two vertical columns separated by a dash (-d-) and then feeds the resulting lines (which look a lot like subtractions :) ) into the calculator bc, which calculates the value of each line.

Upvotes: 0

pakistanprogrammerclub
pakistanprogrammerclub

Reputation: 827

This diffs a bunch of times - I don't recommend it for large numbers of values but it's definitely better than running date in a loop

# 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

Upvotes: 0

choroba
choroba

Reputation: 241968

To add an element to an array, use the += operator:

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

or set the element at the given index:

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

Upvotes: 2

Related Questions