Это фрагмент исходного CSV-файла.
%status,date,job,project,start,end,description
%
//,18.03.2021,sib,sib-dede,07:00,15:00,dede-mongo
%
//,11.06.2021,sib,sib-dede,07:00,15:00,dede-mongo
%
//,24.06.2021,sib,sib-dede,07:00,15:00,dede-mongo
%
?,02.08.2021,sib,sib-accounting,14:35,16:35,business-plan
%
?,13.10.2021,sb,sb-accounting,11:30,12:00,e-mail-pump
Мне нравится извлекать из исходного CSV-файла время начала в столбце 5 и время окончания в столбце 6.
Далее, в зависимости от времени начала и окончания, я предпочитаю рассчитывать продолжительность в часах или минутах (не обращайте внимания).
В конце концов, мне нравится брать исходный файл CSV, вставлять новый столбец между существующими столбцами 6 и 7 с обработанной длительностью и сохранять это добавление в результирующем файле CSV.
Есть ли у кого-нибудь идеи, как решить эту проблему в командной строке GNU Debian Linux?
Я знаю, что могу cut
определённые столбцы из файла CSV вот так.
cut -d, -f5,6 < ./source.csv > ./result.csv
Однако мне все еще не хватает обработки длительности и создания результирующего файла CVS.
PS: Я отдаю предпочтение Bash.
PPS: Есть связанные вопросы, такие как этот, но я не нашел ни одного близкого к этому вопросу.
Да, эти странные %
строки действительно находятся между ними.
Я удалил странные %
строки типа вот это.
пожалуйста, обновите вопрос с ожидаемым результатом
Я подозреваю, что эти «странные строки» на самом деле представляют собой какой-то управляющий символ в вашем столбце %status
, который вы делаете, чтобы выглядеть как строки, в которых всего лишь %
, за которыми следуют строки, начинающиеся с %
или //
, хотя на самом деле это просто %<control char>//
или что-то подобное. строка в начале каждой строки. Вам действительно следует это понять, чтобы получить надежное решение, которое сможет правильно обрабатывать эти поля как есть.
Я отдаю предпочтение Bash
Но вы можете сделать все это за один раз, например. используя mktime
из GNU Awk (при условии, что знаки %
(или последующие символы новой строки) в вашем образце являются просто опечаткой и что время в столбце 6 больше, чем время в столбце 5, в противном случае результат будет отрицательным):
awk -F , -v OFS=, '{
$8=$7; $7=(
mktime(sprintf("0 0 0 %d %d 0", substr($6,1,2), substr($6,4,2))) -
mktime(sprintf("0 0 0 %d %d 0", substr($5,1,2), substr($5,4,2)))
) / 60; print
}' source.csv
Ваше здоровье! Я удалил странные строки %, такие как это. Однако расчет продолжительности еще не завершен. Для продолжительности менее часа этот ответ округляется до следующего полного часа в большую или меньшую сторону.
Сначала я думал, что нужно заменить substr($6,3,2)
на substr($6,3,4)
и так далее, но оказалось, что этого недостаточно.
Теперь я понял! Вам нужно заменить substr($6,3,2)
на substr($6,4,2)
и substr($5,3,2)
на substr($5,4,2)
. Не могли бы вы изменить свой ответ, чтобы я мог отметить его как решение?
@dancesWithCycles Да, извините за опечатку, спасибо, что заметили! substr("14:35",3,2)
произвел бы :3
, но нам нужно substr("14:35",4,2)
, чтобы получить 35
.
Предполагая, что:
%
, за которыми следуют строки, начинающиеся с //
или ?
во входных данных, иdiff
, для добавляемого столбца.затем используя любой awk:
$ awk '
BEGIN { FS=OFS = "," }
NF > 1 {
if ( NR == 1 ) {
diff = "diff"
}
else {
split($5, b, ":")
split($6, e, ":")
beg = b[1]*60 + b[2]
end = e[1]*60 + e[2]
diff = end - beg
}
$6 = $6 OFS diff
print
}
' file
%status,date,job,project,start,end,diff,description
//,18.03.2021,sib,sib-dede,07:00,15:00,480,dede-mongo
//,11.06.2021,sib,sib-dede,07:00,15:00,480,dede-mongo
//,24.06.2021,sib,sib-dede,07:00,15:00,480,dede-mongo
?,02.08.2021,sib,sib-accounting,14:35,16:35,120,business-plan
?,13.10.2021,sb,sb-accounting,11:30,12:00,30,e-mail-pump
Не нужно сначала запускать grep
— передача grep в awk является антипаттерном, см. https://porkmail.org/era/unix/award#grep.
Между ними действительно есть эти странные
%
строчки?