У меня есть следующий текстовый файл (file.dat
):
random text 2019-10-10 20:22:33.456000^ text random 2019-11-30 23:45:56.789000 random
2019-11-11 21:22:33.456000 random stuffs,2019-10-31 23:45:56.789000
random, random 2019-10-10 20:22:33.456000^ text everywhere 2019-12-31 23:45:56.789000
Моя цель - добавить 7 часов к каждой отметке времени ('ГГГГ-ММ-ДД ЧЧ: ММ: СС') в этом текстовый файл.
Требуемый вывод выглядит следующим образом:
random text 2019-10-11 03:22:33.456000^ text random 2019-12-01 06:45:56.789000 random
2019-11-12 04:22:33.456000 random stuffs,2019-11-01 06:45:56.789000
random, random 2019-10-11 03:22:33.456000^ text everywhere 2020-01-01 06:45:56.789000
В настоящее время у меня есть решение для этого, но для текстового файла с 10 000 строк это занимает до 1 минуты. Мой текущий способ выглядит следующим образом:
awk '{ip=$0;while(match(ip,/[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9]/,a)){ cmd="date +\"%F %T\" -d \"" a[0] " 7 hours \""; cmd | getline b; close(cmd); sub(a[0],b$0);ip=substr(ip,RSTART+RLENGTH)}; print $0}' file.dat
Это занимает слишком много времени, так как мои текстовые файлы могут содержать до 1 000 000 строк. Кроме того, я еще не проверял, но я думаю, что функция sub
может вызвать проблемы.
Поэтому я пытался найти другие варианты:
с использованием sed
:
sed "s#([0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2})#$(date -d '\1' +'%F %T')#g" file.dat
Конечно, это не сработало, выдав ошибку invalid date \\1'
. Не удивительно, потому что я не ожидал, что обратная ссылка сработает внутри.
Использование awk
:
awk '{print gensub(/([0-9][0-9][0-9][0-9])-([0-9][0-9])-([0-9][0-9]) ([0-9][0-9]):([0-9][0-9]):([0-9][0-9])/,strftime("%Y-%m-%d %H:%M:%S",mktime("\\1 \\2 \\3 \\4 \\5 \\6")),"g",$0)}' file.dat
Я надеялся с этим, но вывод был неправильным:
random text 1970-01-01 06:59:59.456000^ text random 1970-01-01 06:59:59.789000 random
1970-01-01 06:59:59.456000 random stuffs,1970-01-01 06:59:59.789000
random, random 1970-01-01 06:59:59.456000^ text everywhere 1970-01-01 06:59:59.789000
Все метки времени стали 1970-01-01 06:59:59, что в основном означает mktime
возвращено -1
.
Есть ли другие варианты? Подойдет любой эффективный способ (с использованием bash).