2016-08-27 2 views
0

У меня есть массив ${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 

Кто-нибудь узнать, что я здесь отсутствует или есть лучший способ вычесть раз время.

+0

Я действительно не понимаю, почему вам нужно использовать эпоху, если у вас всего лишь часы + минуты (которые относятся к одному и тому же дню или они неполны) –

+0

Я считаю, что это приведет к ошибочному результату, когда элемент timearray перевернулся на 00:00, а соответствующий элемент productarray все еще находится в 23:59. – thatsboot3101

ответ

2

Чтобы добавить элемент в массив, используйте += оператор:

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

или установить элемент по данному индексу:

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

должно быть '$ l' слева. –

+1

@ Jean-FrançoisFabre не верно, индексы массивов всегда являются арифметическим контекстом, поэтому им не нужен '' '. – kojiro

+0

Спасибо! Это сработало. Я забыл указать, какой элемент массива находится внутри цикла. Каждая итерация перезаписывает один элемент, оставляя только последнюю итерацию единственным элементом. Теперь имеет смысл. – thatsboot3101

0

Это Diffs кучу раз - я не» t рекомендуют его для большого количества значений, но это определенно лучше, чем срок службы в петле

# 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 
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-), а затем подает полученные линии (которые выглядят много как вычитания :)) в калькулятор bc, который вычисляет значение каждой строки.