bash: расписание и циклы - PullRequest
       11

bash: расписание и циклы

0 голосов
/ 28 сентября 2019

Я энтузиаст bash.Я написал много сценариев, но на этот раз я думаю, что этот слишком велик для меня.Я работаю над сценарием, который проверяет количество часов на основе расписания из файла и суммирует их.

У меня есть файл с недельным расписанием.Используя grep, он возвращает мне расписание (например, 13:00 - 20:30 или 13:30 - 21:30).Эти файлы всегда будут в одном и том же формате, только часы будут другими, поэтому мой запрос grep всегда будет работать.Единственное отличие состоит в том, что иногда он возвращает четыре строки (с часами), иногда меньше, иногда больше, зависит от того, что находится в данном файле (я всегда могу использовать grep -c, если число этих строк имеет значение).

Когда я вычитаю время окончания из времени начала, результат будет правильным, хотя он не будет работать, если часы немного нечетны (например, 14:00 - 16:17).Как я могу достичь этого (2 часа и 17 минут)?

И тогда я думаю, что я должен использовать цикл.Я попробовал пару вещей, но запутался и решил приехать сюда.

Вот что у меня получилось (26to31 августа, очевидно, файл с расписанием).

#!/bin/bash


#COUNT=$(grep -c '[0-9][0-9]:[0-9][0-9]' 26to31August)
FINISH=$(grep '[0-9][0-9]:[0-9][0-9]' 26to31August |head -1 |awk '{ print $3 }')
START=$(grep '[0-9][0-9]:[0-9][0-9]' 26to31August |head -1 |awk '{ print $1 }')



VAR1=$(date -d "${FINISH}" +%s)
VAR2=$(date -d "${START}" +%s)

HOURS=$((VAR1-VAR2))


SECS2HOURS=$(expr $HOURS / 3600)
echo "That day it's $SECS2HOURS hours"

Я хочу, чтобы скрипт повторял каждую из этих строк, сообщая мне, сколько часов в каждой строке, а затем складывал их все вместе.

Должен ли я использовать цикл For?Должен ли я использовать функцию в цикле?

Буду признателен за ваши ответы.

Ответы [ 2 ]

0 голосов
/ 28 сентября 2019

Да, вы бы использовали цикл.Вы должны сохранить промежуточный итог в секундах и преобразовать его в часы: минуты в конечном выводе

Первая мысль (предупреждение, этот код содержит ошибку)

total=0
grep '[0-9][0-9]:[0-9][0-9]' 26to31August | while read -r start x finish x; do
    a=$( date -d "$start" "+%s" )
    b=$( date -d "$finish" "+%s" )
    (( total += b - a ))
done

# output
hours=$(( total / 3600 ))
minutes=$(( (total % 2600) / 60 ))
printf "%d:%02d\n" $hours $minutes

bash может проанализировать строку, разделенную пробелами, в слова с помощью команды read.

Где ошибка?В конфигурации bash по умолчанию каждая команда в конвейере выполняется в отдельной подоболочке .Таким образом, содержимое переменной total будет потеряно, когда подоболочка, выполняющая цикл while, завершится .

Вот два способа обойти это:

  1. сгруппировать выходные команды в один и тот же подоболочек

    total=0
    grep '[0-9][0-9]:[0-9][0-9]' 26to31August | {
        while read -r start x finish x; do
            a=$( date -d "$start" "+%s" )
            b=$( date -d "$finish" "+%s" )
            (( total += b - a ))
        done
        hours=$(( total / 3600 ))
        minutes=$(( (total % 2600) / 60 ))
        printf "%d:%02d\n" $hours $minutes
    }
    
  2. не использовать канал, перенаправить вывод подстановки процесса вцикл while

    total=0
    
    while read -r start x finish x; do
        a=$( date -d "$start" "+%s" )
        b=$( date -d "$finish" "+%s" )
        (( total += b - a ))
    done < <( grep '[0-9][0-9]:[0-9][0-9]' 26to31August )
    
    hours=$(( total / 3600 ))
    minutes=$(( (total % 2600) / 60 ))
    printf "%d:%02d\n" $hours $minutes
    

Примечание. Не используйте имена переменных ALLCAPS. слишком легко случайно перезаписать важные переменные оболочки .

0 голосов
/ 28 сентября 2019

Возможно, это не то, что вы хотите услышать, но это определенно тот случай, когда другой язык программирования будет работать бесконечно лучше, чем арифметика Bash.Например, в Python вы просто делаете duration = finish - start.Это будет производить расчеты с учетом часовых поясов, с учетом високосных дней, в результате чего получится объект, из которого вы сможете получить все от лет до доли секунды.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...