С другой стороны, не могли бы вы использовать timeкоманду?
Anishsane
Вместо этого используйте unix time date +%s, затем вычтите, чтобы получить разницу в секундах.
roblogic
Ответы:
476
Bash имеет удобную SECONDSвстроенную переменную, которая отслеживает количество секунд, прошедших с момента запуска оболочки. Эта переменная сохраняет свои свойства при присваивании, а значение, возвращаемое после присваивания, представляет собой количество секунд с момента присваивания плюс присвоенное значение.
Таким образом, вы можете просто установить SECONDS0 перед запуском SECONDSвременного события, просто прочитать после события и выполнить арифметику времени перед отображением.
SECONDS=0# do some work
duration=$SECONDS
echo "$(($duration / 60)) minutes and $(($duration % 60)) seconds elapsed."
Поскольку это решение не зависит от date +%s(которое является расширением GNU), оно переносимо на все системы, поддерживаемые Bash.
+1. Кстати, вы можете обмануть, dateвыполнив арифметику времени для себя, написав date -u -d @"$diff" +'%-Mm %-Ss'. (Это интерпретируется $diffкак секунды с начала эпохи и вычисляет минуты и секунды в UTC.) Это, вероятно, не так уж и элегантно, просто лучше запутано. :-P
ruakh
13
Красиво и просто. Если кому-то нужны часы:echo "$(($diff / 3600)) hours, $((($diff / 60) % 60)) minutes and $(($diff % 60)) seconds elapsed."
Ча
6
Это должно быть прочитано, $(date -u +%s)чтобы предотвратить состояние гонки в даты, когда переключено летнее время. И остерегайтесь злых високосных секунд;)
Тино
3
@ daniel-kamil-kozar Хорошая находка. Однако это немного хрупко. Существует только одна такая переменная, поэтому ее нельзя использовать рекурсивно для измерения производительности, а еще хуже - после unset SECONDSтого , как она исчезнет:echo $SECONDS; unset SECONDS; SECONDS=0; sleep 3; echo $SECONDS
Tino
6
@ParthianShot: Мне жаль, что вы так думаете. Однако я считаю, что этот ответ - то, что нужно большинству людей при поиске ответов на такой вопрос: чтобы измерить, сколько времени прошло между событиями, а не рассчитать время.
Даниэль Камил Козар
99
секунд
Для измерения прошедшего времени (в секундах) нам нужно:
целое число, представляющее количество прошедших секунд и
способ конвертировать такое целое число в пригодный для использования формат.
Целочисленное значение прошедших секунд:
Существует два внутренних способа bash найти целое значение по количеству прошедших секунд:
Переменная Bash SECONDS (если SECONDS не установлена, она теряет свое специальное свойство).
Установка значения SECONDS на 0:
SECONDS=0
sleep 1# Process to execute
elapsedseconds=$SECONDS
Сохранение значения переменной SECONDSв начале:
a=$SECONDS
sleep 1# Process to execute
elapsedseconds=$(( SECONDS - a ))
Опция Bash Printf %(datefmt)T:
a="$(TZ=UTC0 printf '%(%s)T\n' '-1')"### `-1` is the current time
sleep 1### Process to execute
elapsedseconds=$(( $(TZ=UTC0 printf '%(%s)T\n''-1')- a ))
Преобразовать такое целое число в пригодный для использования формат
%(FORMAT)Tвыводит строку даты и времени, полученную в результате использования FORMAT в качестве строки формата для strftime(3). Связанный аргумент - это количество секунд с начала эпохи , или -1 (текущее время) или -2 (время запуска оболочки). Если соответствующий аргумент не указан, по умолчанию используется текущее время.
Так что вы можете просто позвонить, textifyDuration $elpasedsecondsгде textifyDurationеще одна реализация длительной печати:
Чтобы получить форматированное время, мы должны использовать внешний инструмент (GNU date) несколькими способами, чтобы получить почти годичный результат, включая наносекунды.
Математика внутри даты.
Нет необходимости во внешней арифметике, сделайте все за один шаг date:
date -u -d "0 $FinalDate seconds - $StartDate seconds"+"%H:%M:%S"
Да, 0в командной строке есть ноль. Необходимо.
Это предполагает, что вы можете изменить date +"%T"команду на date +"%s"команду, чтобы значения сохранялись (печатались) в считанные секунды.
Обратите внимание, что команда ограничена:
Положительные значения $StartDateи $FinalDateсекунды.
Значение в $FinalDateбольше (позже), чем $StartDate.
Разница во времени меньше 24 часов.
Вы принимаете формат вывода с часами, минутами и секундами. Очень легко изменить.
Допустимо использовать время -u UTC. Чтобы избежать "DST" и местное время корректировки.
Если вы должны использовать 10:33:56строку, ну, просто преобразуйте ее в секунды,
также, слово секунд может быть сокращено как сек:
Если требуется рассчитать более длительную (до 364 дней) разницу во времени, мы должны использовать начало (некоторый) год в качестве справочного материала и значение формата %j(номер дня в году):
Похожий на:
string1="+10 days 10:33:56.5400022"
string2="+35 days 10:36:10.8800056"StartDate=$(date -u -d "2000/1/1 $string1"+"%s.%N")FinalDate=$(date -u -d "2000/1/1 $string2"+"%s.%N")
date -u -d "2000/1/1 $FinalDate sec - $StartDate sec"+"%j days %H:%M:%S.%N"Output:026 days 00:02:14.340003400
К сожалению, в этом случае нам нужно вручную вычесть 1ОДИН из числа дней. Команда date рассматривает первый день года как 1. Не так сложно ...
Инструмент, используемый на небольших устройствах (очень маленький исполняемый файл для установки): Busybox.
Либо сделайте ссылку на busybox с названием date:
$ ln -s /bin/busybox date
Затем используйте его, вызвав его date(поместите в каталог, включенный в PATH).
Или сделайте псевдоним как:
$ alias date='busybox date'
У даты Busybox есть приятная опция: -D, чтобы получить формат ввода времени. Это открывает много форматов, которые будут использоваться как время. Используя опцию -D, мы можем напрямую преобразовать время 10:33:56:
date -D "%H:%M:%S"-d "10:33:56"+"%Y.%m.%d-%H:%M:%S"
И как вы можете видеть из вывода Команды выше, день считается «сегодняшним». Чтобы узнать время начала эпохи:
$ string1="10:33:56"
$ date -u -D "%Y.%m.%d-%H:%M:%S"-d "1970.01.01-$string1"+"%Y.%m.%d-%H:%M:%S"1970.01.01-10:33:56
Дата Busybox может даже получить время (в формате выше) без -D:
$ date -u -d "1970.01.01-$string1"+"%Y.%m.%d-%H:%M:%S"1970.01.01-10:33:56
И формат вывода может быть даже секунды с начала эпохи.
$ date -u -d "1970.01.01-$string1"+"%s"52436
Для обоих раз и немного bash math (busybox не может сделать математику, пока):
Это такой удивительный ответ, охватывающий множество оснований и прекрасных объяснений. Спасибо!
Деви
Мне пришлось искать %(FORMAT)Tстроку, переданную printfкоманде, встроенной в bash. От bash-hackers.org : %(FORMAT)Tвывести строку даты и времени, полученную в результате использования FORMATв качестве строки формата для strftime (3). Связанный аргумент - это количество секунд с начала эпохи, или -1 (текущее время) или -2 (время запуска оболочки). Если соответствующий аргумент не указан, по умолчанию используется текущее время . Это эзотерика. В данном случае, %sкак указано, strftime(3)это «количество секунд с начала эпохи».
Чем это отличается от моего решения? Я действительно не вижу выгоды от вызова awkв этом случае, так как Bash одинаково хорошо обрабатывает целочисленную арифметику.
Даниэль Камиль Козар
1
Ваш ответ тоже правильный. Некоторые люди, такие как я, предпочитают работать с awk, а не с bash несоответствиями.
Дориан
2
Не могли бы вы подробнее рассказать о несоответствиях в Bash относительно целочисленной арифметики? Я хотел бы знать больше об этом, так как я не знал ни о чем.
Даниэль Камил Козар
12
Я просто искал это. Я не понимаю критику этого ответа. Мне нравится видеть больше, чем одно решение проблемы. И я - тот, кто предпочитает awkкоманды bash (если ни для чего другого, потому что awk работает в других оболочках). Мне понравилось это решение лучше. Но это мое личное мнение.
rpsml
4
Ведущие нули: echo $ ((END-START)) | awk '{printf "% 02d:% 02d \ n", int ($ 1/60), int ($ 1% 60)}'
Я искал что-то вроде вашего date метода GNU . Genius.
Хаоммару
Пожалуйста, удалите мой комментарий ... извините
Билл Гейл
После установки dateutilsчерез apt команды не было datediff- пришлось использовать dateutils.ddiff.
Сюзана
12
Я хотел бы предложить другой способ избежать повторного вызова dateкоманды. Это может быть полезно в случае, если вы уже собрали временные метки в %Tформате даты:
ts_get_sec(){
read -r h m s <<< $(echo $1 | tr ':'' ')
echo $(((h*60*60)+(m*60)+s))}
start_ts=10:33:56
stop_ts=10:36:10
START=$(ts_get_sec $start_ts)
STOP=$(ts_get_sec $stop_ts)
DIFF=$((STOP-START))
echo "$((DIFF/60))m $((DIFF%60))s"
мы даже можем обрабатывать миллисекунды таким же образом.
ts_get_msec(){
read -r h m s ms <<< $(echo $1 | tr '.:'' ')
echo $(((h*60*60*1000)+(m*60*1000)+(s*1000)+ms))}
start_ts=10:33:56.104
stop_ts=10:36:10.102
START=$(ts_get_msec $start_ts)
STOP=$(ts_get_msec $stop_ts)
DIFF=$((STOP-START))
min=$((DIFF/(60*1000)))
sec=$(((DIFF%(60*1000))/1000))
ms=$(((DIFF%(60*1000))%1000))
echo "${min}:${sec}.$ms"
Есть ли способ справиться с миллисекундами, например, 10: 33: 56.104
Умеш Раджбхандари
Обработка миллисекунды ведет себя неправильно, если поле миллисекунды начинается с нуля. Например, ms = "033" даст конечные цифры "027", потому что поле ms интерпретируется как восьмеричное. изменение "echo" ... "+ ms))" на ... "+ $ {ms ## + (0)}))" исправит это до тех пор, пока "shopt -s extglob" появится где-то над этим в скрипт. Вероятно, следует убрать лидирующие нули из h, m и s ...
Эрик Тауэрс,
3
echo $(((60*60*$((10#$h)))+(60*$((10#$m)))+$((10#$s))))работал на меня, так как я получилvalue too great for base (error token is "08")
Никлас
6
Вот немного магии:
time1=14:30
time2=$( date +%H:%M )# 16:00
diff=$( echo "$time2 - $time1"| sed 's%:%+(1/60)*%g'| bc -l )
echo $diff hours
# outputs 1.5 hours
sedзаменяет на :формулу для преобразования в 1/60. Тогда расчет времени, который сделанbc
Вот решение, использующее только dateвозможности команд с использованием «назад» и не использующее вторую переменную для хранения времени окончания:
#!/bin/bash# save the current time
start_time=$( date +%s.%N )# tested program
sleep 1# the current time after the program has finished# minus the time when we started, in seconds.nanoseconds
elapsed_time=$( date +%s.%N --date="$start_time seconds ago")
echo elapsed_time: $elapsed_time
Некоторая обработка строк может удалить эти пустые значения
date -ujf%s $(($(date -jf%T "10:36:10"+%s)- $(date -jf%T "10:33:56"+%s))) \
+'%-Hh %-Mm %-Ss'| sed "s/[[:<:]]0[hms] *//g"# 2m 14s
Это не сработает, если вы разместите более раннее время первым Если вам нужно с этим справиться, измените $(($(date ...) - $(date ...)))на$(echo $(date ...) - $(date ...) | bc | tr -d -)
$ units
2411 units,71 prefixes,33 nonlinear units
You have:(10hr+36min+10s)-(10hr+33min+56s)You want: s
*134/0.0074626866You have:(10hr+36min+10s)-(10hr+33min+56s)You want: min
*2.2333333/0.44776119
Я понимаю, что это старый пост, но я натолкнулся на него сегодня, работая над сценарием, который будет брать даты и время из файла журнала и вычислять дельту. Сценарий ниже, безусловно, излишний, и я настоятельно рекомендую проверить мою логику и математику.
#!/bin/bash
dTime=""
tmp=""#firstEntry="$(head -n 1 "$LOG" | sed 's/.*] \([0-9: -]\+\).*/\1/')"
firstEntry="2013-01-16 01:56:37"#lastEntry="$(tac "$LOG" | head -n 1 | sed 's/.*] \([0-9: -]\+\).*/\1/')"
lastEntry="2014-09-17 18:24:02"# I like to make the variables easier to parse
firstEntry="${firstEntry//-/ }"
lastEntry="${lastEntry//-/ }"
firstEntry="${firstEntry//:/ }"
lastEntry="${lastEntry//:/ }"# remove the following lines in production
echo "$lastEntry"
echo "$firstEntry"# compute days in last entryfor i in`seq 1 $(echo $lastEntry|awk '{print $2}')`;do{case"$i"in1|3|5|7|8|10|12)
dTime=$(($dTime+31));;4|6|9|11)
dTime=$(($dTime+30));;2)
dTime=$(($dTime+28));;esac}done# do leap year calculations for all years between first and last entryfor i in`seq $(echo $firstEntry|awk '{print $1}') $(echo $lastEntry|awk '{print $1}')`;do{if[ $(($i%4))-eq 0]&&[ $(($i%100))-eq 0]&&[ $(($i%400))-eq 0];then{if["$i"="$(echo $firstEntry|awk '{print $1}')"]&&[ $(echo $firstEntry|awk '{print $2}')-lt 2];then{
dTime=$(($dTime+1))}elif[ $(echo $firstEntry|awk '{print $2}')-eq 2]&&[ $(echo $firstEntry|awk '{print $3}')-lt 29];then{
dTime=$(($dTime+1))}fi}elif[ $(($i%4))-eq 0]&&[ $(($i%100))-ne 0];then{if["$i"="$(echo $lastEntry|awk '{print $1}')"]&&[ $(echo $lastEntry|awk '{print $2}')-gt 2];then{
dTime=$(($dTime+1))}elif[ $(echo $lastEntry|awk '{print $2}')-eq 2]&&[ $(echo $lastEntry|awk '{print $3}')-ne 29];then{
dTime=$(($dTime+1))}fi}fi}done# substract days in first entryfor i in`seq 1 $(echo $firstEntry|awk '{print $2}')`;do{case"$i"in1|3|5|7|8|10|12)
dTime=$(($dTime-31));;4|6|9|11)
dTime=$(($dTime-30));;2)
dTime=$(($dTime-28));;esac}done
dTime=$(($dTime+$(echo $lastEntry|awk '{print $3}')-$(echo $firstEntry|awk '{print $3}')))# The above gives number of days for sample. Now we need hours, minutes, and seconds# As a bit of hackery I just put the stuff in the best order for use in a for loop
dTime="$(($(echo $lastEntry|awk '{print $6}')-$(echo $firstEntry|awk '{print $6}'))) $(($(echo $lastEntry|awk '{print $5}')-$(echo $firstEntry|awk '{print $5}'))) $(($(echo $lastEntry|awk '{print $4}')-$(echo $firstEntry|awk '{print $4}'))) $dTime"
tmp=1for i in $dTime;do{if[ $i -lt 0];then{case"$tmp"in1)
tmp="$(($(echo $dTime|awk '{print $1}')+60)) $(($(echo $dTime|awk '{print $2}')-1))"
dTime="$tmp $(echo $dTime|awk '{print $3""$4}')"
tmp=1;;2)
tmp="$(($(echo $dTime|awk '{print $2}')+60)) $(($(echo $dTime|awk '{print $3}')-1))"
dTime="$(echo $dTime|awk '{print $1}') $tmp $(echo $dTime|awk '{print $4}')"
tmp=2;;3)
tmp="$(($(echo $dTime|awk '{print $3}')+24)) $(($(echo $dTime|awk '{print $4}')-1))"
dTime="$(echo $dTime|awk '{print $1""$2}') $tmp"
tmp=3;;esac}fi
tmp=$(($tmp+1))}done
echo "The sample time is $(echo $dTime|awk '{print $4}') days, $(echo $dTime|awk '{print $3}') hours, $(echo $dTime|awk '{print $2}') minutes, and $(echo $dTime|awk '{print $1}') seconds."
Вы получите вывод следующим образом.
2012101601563720140917182402The sample time is 700 days,16 hours,27 minutes, and 25 seconds.
Я немного изменил сценарий, чтобы сделать его автономным (то есть просто установить значения переменных), но, возможно, общая идея также встречается. Вы могли бы хотеть некоторую дополнительную проверку ошибок для отрицательных значений.
Вот моя реализация bash (с битами, взятыми из других SO ;-)
function countTimeDiff(){
timeA=$1 # 09:59:35
timeB=$2 # 17:32:55# feeding variables by using read and splitting with IFS
IFS=: read ah am as <<<"$timeA"
IFS=: read bh bm bs <<<"$timeB"# Convert hours to minutes.# The 10# is there to avoid errors with leading zeros# by telling bash that we use base 10
secondsA=$((10#$ah*60*60 + 10#$am*60 + 10#$as))
secondsB=$((10#$bh*60*60 + 10#$bm*60 + 10#$bs))
DIFF_SEC=$((secondsB - secondsA))
echo "The difference is $DIFF_SEC seconds.";
SEC=$(($DIFF_SEC%60))
MIN=$((($DIFF_SEC-$SEC)%3600/60))
HRS=$((($DIFF_SEC-$MIN*60)/3600))
TIME_DIFF="$HRS:$MIN:$SEC";
echo $TIME_DIFF;}
$ countTimeDiff 2:15:552:55:16The difference is 2361 seconds.0:39:21
time
команду?date +%s
, затем вычтите, чтобы получить разницу в секундах.Ответы:
Bash имеет удобную
SECONDS
встроенную переменную, которая отслеживает количество секунд, прошедших с момента запуска оболочки. Эта переменная сохраняет свои свойства при присваивании, а значение, возвращаемое после присваивания, представляет собой количество секунд с момента присваивания плюс присвоенное значение.Таким образом, вы можете просто установить
SECONDS
0 перед запускомSECONDS
временного события, просто прочитать после события и выполнить арифметику времени перед отображением.Поскольку это решение не зависит от
date +%s
(которое является расширением GNU), оно переносимо на все системы, поддерживаемые Bash.источник
date
выполнив арифметику времени для себя, написавdate -u -d @"$diff" +'%-Mm %-Ss'
. (Это интерпретируется$diff
как секунды с начала эпохи и вычисляет минуты и секунды в UTC.) Это, вероятно, не так уж и элегантно, просто лучше запутано. :-Pecho "$(($diff / 3600)) hours, $((($diff / 60) % 60)) minutes and $(($diff % 60)) seconds elapsed."
$(date -u +%s)
чтобы предотвратить состояние гонки в даты, когда переключено летнее время. И остерегайтесь злых високосных секунд;)unset SECONDS
того , как она исчезнет:echo $SECONDS; unset SECONDS; SECONDS=0; sleep 3; echo $SECONDS
секунд
Для измерения прошедшего времени (в секундах) нам нужно:
Целочисленное значение прошедших секунд:
Существует два внутренних способа bash найти целое значение по количеству прошедших секунд:
Переменная Bash SECONDS (если SECONDS не установлена, она теряет свое специальное свойство).
Установка значения SECONDS на 0:
Сохранение значения переменной
SECONDS
в начале:Опция Bash Printf
%(datefmt)T
:Преобразовать такое целое число в пригодный для использования формат
Внутренний bash
printf
может сделать это напрямую:так же
но это не удастся в течение более 24 часов, поскольку мы на самом деле выводим время на стене, а не длительность:
Для любителей деталей, от bash-hackers.org :
Так что вы можете просто позвонить,
textifyDuration $elpasedseconds
гдеtextifyDuration
еще одна реализация длительной печати:Дата GNU.
Чтобы получить форматированное время, мы должны использовать внешний инструмент (GNU date) несколькими способами, чтобы получить почти годичный результат, включая наносекунды.
Математика внутри даты.
Нет необходимости во внешней арифметике, сделайте все за один шаг
date
:Да,
0
в командной строке есть ноль. Необходимо.Это предполагает, что вы можете изменить
date +"%T"
команду наdate +"%s"
команду, чтобы значения сохранялись (печатались) в считанные секунды.Обратите внимание, что команда ограничена:
$StartDate
и$FinalDate
секунды.$FinalDate
больше (позже), чем$StartDate
.Если вы должны использовать
10:33:56
строку, ну, просто преобразуйте ее в секунды,также, слово секунд может быть сокращено как сек:
Обратите внимание, что преобразование времени в секундах (как показано выше) относится к началу «этого» дня (сегодня).
Концепция может быть расширена до наносекунд, например:
Если требуется рассчитать более длительную (до 364 дней) разницу во времени, мы должны использовать начало (некоторый) год в качестве справочного материала и значение формата
%j
(номер дня в году):Похожий на:
К сожалению, в этом случае нам нужно вручную вычесть
1
ОДИН из числа дней. Команда date рассматривает первый день года как 1. Не так сложно ...Использование большого количества секунд допустимо и задокументировано здесь:
https://www.gnu.org/software/coreutils/manual/html_node/Examples-of-date.html#Examples-of-date.
Дата занятости
Инструмент, используемый на небольших устройствах (очень маленький исполняемый файл для установки): Busybox.
Либо сделайте ссылку на busybox с названием date:
Затем используйте его, вызвав его
date
(поместите в каталог, включенный в PATH).Или сделайте псевдоним как:
У даты Busybox есть приятная опция: -D, чтобы получить формат ввода времени. Это открывает много форматов, которые будут использоваться как время. Используя опцию -D, мы можем напрямую преобразовать время 10:33:56:
И как вы можете видеть из вывода Команды выше, день считается «сегодняшним». Чтобы узнать время начала эпохи:
Дата Busybox может даже получить время (в формате выше) без -D:
И формат вывода может быть даже секунды с начала эпохи.
Для обоих раз и немного bash math (busybox не может сделать математику, пока):
Или в формате:
источник
%(FORMAT)T
строку, переданнуюprintf
команде, встроенной в bash. От bash-hackers.org :%(FORMAT)T
вывести строку даты и времени, полученную в результате использованияFORMAT
в качестве строки формата для strftime (3). Связанный аргумент - это количество секунд с начала эпохи, или -1 (текущее время) или -2 (время запуска оболочки). Если соответствующий аргумент не указан, по умолчанию используется текущее время . Это эзотерика. В данном случае,%s
как указано,strftime(3)
это «количество секунд с начала эпохи».Вот как я это сделал:
На самом деле, возьмите количество секунд в начале, затем количество секунд в конце и выведите разницу в минутах: секундах.
источник
awk
в этом случае, так как Bash одинаково хорошо обрабатывает целочисленную арифметику.awk
команды bash (если ни для чего другого, потому что awk работает в других оболочках). Мне понравилось это решение лучше. Но это мое личное мнение.Другой вариант - использовать
datediff
сdateutils
( http://www.fresse.org/dateutils/#datediff ):Вы также можете использовать
gawk
.mawk
1.3.4 также имеетstrftime
иmktime
но более старые версииmawk
иnawk
не делают.Или вот еще один способ сделать это с помощью GNU
date
:источник
date
метода GNU . Genius.dateutils
через apt команды не былоdatediff
- пришлось использоватьdateutils.ddiff
.Я хотел бы предложить другой способ избежать повторного вызова
date
команды. Это может быть полезно в случае, если вы уже собрали временные метки в%T
формате даты:мы даже можем обрабатывать миллисекунды таким же образом.
источник
echo $(((60*60*$((10#$h)))+(60*$((10#$m)))+$((10#$s))))
работал на меня, так как я получилvalue too great for base (error token is "08")
Вот немного магии:
sed
заменяет на:
формулу для преобразования в 1/60. Тогда расчет времени, который сделанbc
источник
На сегодняшний день (GNU coreutils) 7.4 теперь вы можете использовать -d для выполнения арифметики:
Единицами, которые вы можете использовать, являются дни, годы, месяцы, часы, минуты и секунды:
источник
Исходя из ответа Даниэля Камиля Козара, показать часы / минуты / секунды:
Таким образом, полный сценарий будет:
источник
Или заверните немного
Тогда это работает.
источник
Вот решение, использующее только
date
возможности команд с использованием «назад» и не использующее вторую переменную для хранения времени окончания:это дает:
источник
источник
date
.date
может дать вам разницу и отформатировать ее для вас (показаны варианты OS X)Некоторая обработка строк может удалить эти пустые значения
Это не сработает, если вы разместите более раннее время первым Если вам нужно с этим справиться, измените
$(($(date ...) - $(date ...)))
на$(echo $(date ...) - $(date ...) | bc | tr -d -)
источник
Мне нужен скрипт разницы во времени для использования с
mencoder
(--endpos
это относительно), и мое решение заключается в вызове скрипта Python:доли секунд также поддерживаются:
и он может сказать вам, что разница между 200 и 120 составляет 1 ч 20 м:
и может преобразовывать любое (возможно, дробное) число секунд, минут или часов в чч: мм: сс
timediff.py:
источник
С GNU
units
:источник
Обобщение решения @ nisetama с использованием даты GNU (верный Ubuntu 14.04 LTS):
получая:
источник
источник
Определите эту функцию (скажем, в ~ / .bashrc):
Теперь вы можете измерить время частей ваших скриптов:
очень полезно найти узкие места исполнения.
источник
Я понимаю, что это старый пост, но я натолкнулся на него сегодня, работая над сценарием, который будет брать даты и время из файла журнала и вычислять дельту. Сценарий ниже, безусловно, излишний, и я настоятельно рекомендую проверить мою логику и математику.
Вы получите вывод следующим образом.
Я немного изменил сценарий, чтобы сделать его автономным (то есть просто установить значения переменных), но, возможно, общая идея также встречается. Вы могли бы хотеть некоторую дополнительную проверку ошибок для отрицательных значений.
источник
Я не могу комментировать ответ mcaleaa, поэтому я публикую это здесь. Переменная diff должна быть в маленьком регистре. Вот пример.
Предыдущая переменная была объявлена в нижнем регистре. Это то, что произошло, когда используется верхний регистр.
Итак, быстрое исправление будет так
источник
Вот моя реализация bash (с битами, взятыми из других SO ;-)
Не проверено, может быть глючит.
источник