Как добавить два временных вывода в bash - PullRequest
4 голосов
/ 29 декабря 2011

Я хочу посчитать в bash среднее время, потраченное несколькими командами.Вывод команды времени: min: sec.milisec.

Я не знаю, как добавить два вывода такого рода в bash и в конечном итоге для вычисления среднего значения.

Я пытался преобразовать выходные данные с датой, но вывод «дата: недействительная дата` 0: 01.00 '».

Ответы [ 2 ]

6 голосов
/ 29 декабря 2011

Это ответ из трех частей

Часть первая

Сначала используйте переменную TIMEFORMAT, чтобы вывести только прошедшие секунды. Тогда вы можете добавить это непосредственно

С man bash

TIMEFORMAT Значение этого параметра используется в качестве строки формата, определяющей, как информация о синхронизации для конвейеров с префиксом зарезервированного времени должно отображаться слово. Характер вводит escape-последовательность, которая расширяется до значения времени или другой информации. escape-последовательности и их значения следующие; фигурные скобки обозначают необязательные части.

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

TIMEFORMAT='%0R'; time sleep 1
1

Часть вторая

Во-вторых, как мы фиксируем вывод time? Это на самом деле немного сложно, вот как вы фиксируете время из команды выше

TIMEFORMAT='%0R'; time1=$( { time sleep 1; } 2>&1 )

Часть третья

Как сложить время и получить среднее значение?

В bash мы используем конструкцию $(( )) для математики. Обратите внимание, что bash изначально не поддерживает с плавающей запятой, поэтому вы будете выполнять целочисленное деление (отсюда и точность 0.) Вот скрипт, который будет захватывать time из двух команд и выводить каждое из отдельных времен и их среднее значение

#!/bin/bash

TIMEFORMAT='%0R'
time1=$( { time sleep 1; } 2>&1 )
time2=$( { time sleep 4; } 2>&1 )
ave=$(( (time1 + time2) / 2))

echo "time1 is $time1 | time2 is $time2 | average is $ave"

выход

time1 is 1 | time2 is 4 | average is 2

Если целочисленное деление для вас не является началом и вам нужна точность, если вы не против вызова внешнего двоичного файла bc, вы можете сделать это довольно легко.

#!/bin/bash

TIMEFORMAT='%3R'
time1=$( { time sleep 1; } 2>&1 )
time2=$( { time sleep 4; } 2>&1 )
ave=$( bc <<<"scale=3; ($time1 + $time2)/2" )

echo "time1 is $time1 | time2 is $time2 | average is $ave"

выход

time1 is 1.003 | time2 is 4.003 | average is 2.503
1 голос
/ 29 декабря 2011

Для примера я буду использовать предварительно инициализированную переменную:

time="54:32.96";

minutes=$(echo "$time" | cut -d":" -f1)
seconds=$(echo "$time" | cut -d":" -f2 | cut -d"." -f1)
millis=$(echo "$time" | cut -d":" -f2 | cut -d"." -f2)

#Total time in millis
totalMillisOne=$(($millis+$seconds*1000+$minutes*60000))

Вы делаете это с каждой командой и сохраняете ее в различных переменных, а затем делаете среднее:

let avMillis=$totalMillisOne+$totalMillisTwo
let avMillis=$avMillis/2

И вы выводите его в том же формате ввода:

let avSeconds=$avMillis/1000
let avMillis=$avMillis-$avSeconds*1000;

let avMinutes=$avSeconds/60;
let avSeconds=$avSeconds-$avMinutes*60;

echo "${avMinutes}:${avSeconds}.${avMillis}"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...