Используйте прерывание!
tempfiles=( )
cleanup() {
rm -f "${tempfiles[@]}"
}
trap cleanup 0
error() {
local parent_lineno="$1"
local message="$2"
local code="${3:-1}"
if [[ -n "$message" ]] ; then
echo "Error on or near line ${parent_lineno}: ${message}; exiting with status ${code}"
else
echo "Error on or near line ${parent_lineno}; exiting with status ${code}"
fi
exit "${code}"
}
trap 'error ${LINENO}' ERR
... тогда, каждый раз, когда Вы создаете временный файл:
temp_foo="$(mktemp -t foobar.XXXXXX)"
tempfiles+=( "$temp_foo" )
и $temp_foo
будет удален на выходе, и текущий номер строки будет распечатан. (set -e
аналогично даст Вам поведение выхода на ошибке, , хотя оно идет с серьезными протестами и ослабляет предсказуемость и мобильность кода).
можно или позволить вызову прерывания error
для Вас (в этом случае, он использует код выхода по умолчанию 1 и никакое сообщение), или назовите его сами и обеспечьте явные значения; например:
error ${LINENO} "the foobar failed" 2
выйдет с состоянием 2 и даст явное сообщение.
Как насчет этого: создайте небольшую таблицу с 24 * 7 строками, по одной строке на каждый час в неделю.
CREATE TABLE hours (
hour timestamp not null,
is_working boolean not null
);
INSERT INTO hours (hour, is_working) VALUES
('2009-11-2 00:00:00', false),
('2009-11-2 01:00:00', false),
. . .
('2009-11-2 08:00:00', true),
. . .
('2009-11-2 15:00:00', true),
('2009-11-2 16:00:00', false),
. . .
('2009-11-2 23:00:00', false);
Подобным образом добавьте 24 строки для каждого из других дней. Неважно, какой год или месяц вы дадите, как вы сейчас убедитесь. Вам просто нужно представить все семь дней недели.
SELECT t.id, t.start, t.end, SUM(CASE WHEN h.is_working THEN 1 ELSE 0 END) AS hours_worked
FROM mytable t JOIN hours h
ON (EXTRACT(DOW FROM TIMESTAMP h.hour) BETWEEN EXTRACT(DOW FROM TIMESTAMP t.start)
AND EXTRACT(DOW FROM TIMESTAMP t.end))
AND (EXTRACT(DOW FROM TIMESTAMP h.hour) > EXTRACT(DOW FROM TIMESTAMP t.start)
OR EXTRACT(HOUR FROM TIMESTAMP h.hour) >= EXTRACT(HOUR FROM TIMESTAMP t.start))
AND (EXTRACT(DOW FROM TIMESTAMP h.hour) < EXTRACT(DOW FROM TIMESTAMP t.end)
OR EXTRACT(HOUR FROM TIMESTAMP h.hour) <= EXTRACT(HOUR FROM TIMESTAMP t.end))
GROUP BY t.id, t.start, t.end;