Преобразование отформатированных дат в секундах с эпохи

У меня есть файл:

pablo tty8 Thu Nov 1 12:51:21 2012 still logged in (unknown tty8 Thu Nov 1 12:50:57 2012 - Thu Nov 1 12:51:21 2012 (00:00) pablo tty2 Thu Nov 1 12:50:39 2012 still logged in pablo tty7 Thu Nov 1 12:49:45 2012 - Thu Nov 1 12:50:56 2012 (00:01) (unknown tty7 Thu Nov 1 12:34:32 2012 - Thu Nov 1 12:49:45 2012 (00:15) 

Я хочу заменить файл в указанную дату на секунду. Я хочу напечатать:

 pablo tty8 1351770681 still logged in (unknown tty8 1351770657 - 1351770681 (00:00) pablo tty2 1351770639 still logged in pablo tty7 1351770585 - 1351770656 (00:01) (unknown tty7 1351769672 - 1351770585 (00:15) 

Я пробовал эту команду:

 gawk --posix 'function my() {"date -d \047"$0"\047 +%s" | getline b; gsub( /[A-Za-z]{3} [A-Za-z]{3} [0-9] ([0-9]{2}:){2}[0-9]{2} [0-9]{4}/,b );print} { my() }' file 

Вышеуказанная команда не работает:

 $ gawk --posix 'function my() > {"date -d \047"$0"\047 +%s" | getline b; > gsub( /[A-Za-z]{3} [A-Za-z]{3} [0-9] ([0-9]{2}:){2}[0-9]{2} [0-9]{4}/,b ); print} > { my() }' ta date: błędna data: `pablo tty8 Thu Nov 1 12:51:21 2012 still logged in ' pablo tty8 still logged in (unknown tty8 1351897200 - 1351897200 (00:00) date: błędna data: `pablo tty2 Thu Nov 1 12:50:39 2012 still logged in ' pablo tty2 1351897200 still logged in date: błędna data: `pablo tty7 Thu Nov 1 12:49:45 2012 - Thu Nov 1 12:50:56 2012 (00:01) ' pablo tty7 1351897200 - 1351897200 (00:01) (unknown tty7 1351897200 - 1351897200 (00:15) 

Как улучшить приведенную выше команду?

5 Solutions collect form web for “Преобразование отформатированных дат в секундах с эпохи”

Чтобы сделать это по-своему, это должно быть чем-то вроде:

 POSIXLY_CORRECT=1 awk ' { n = ""; r = $0 while (match(r, /[[:alpha:]]{3} [[:alpha:]]{3} +[0-9]+ ([0-9]{2}:){2}[0-9]{2} [0-9]{4}/)) { c = "date -d\"" substr(r,RSTART,RLENGTH) "\" +%s" c | getline b close(c) n = n substr(r,1,RSTART-1) b r = substr(r,RSTART+RLENGTH) } print nr }' 

Вот альтернативный подход (с использованием mktime ):

 #!/bin/awk -f { split($6,A,":"); S1=sprintf("%d %d %d %d %d %d",$7,$4,$5,A[1],A[2],A[3]) T1=mktime(S1) if ($8=="-") { split($12,A,":"); S2=sprintf("%d %d %d %d %d %d",$13,$10,$11,A[1],A[2],A[3]) T2=mktime(S2) print $1,$2,T1,$8,T2,$14 } else { print $1,$2,T1,$8,$9,$10 } } , #!/bin/awk -f { split($6,A,":"); S1=sprintf("%d %d %d %d %d %d",$7,$4,$5,A[1],A[2],A[3]) T1=mktime(S1) if ($8=="-") { split($12,A,":"); S2=sprintf("%d %d %d %d %d %d",$13,$10,$11,A[1],A[2],A[3]) T2=mktime(S2) print $1,$2,T1,$8,T2,$14 } else { print $1,$2,T1,$8,$9,$10 } } , #!/bin/awk -f { split($6,A,":"); S1=sprintf("%d %d %d %d %d %d",$7,$4,$5,A[1],A[2],A[3]) T1=mktime(S1) if ($8=="-") { split($12,A,":"); S2=sprintf("%d %d %d %d %d %d",$13,$10,$11,A[1],A[2],A[3]) T2=mktime(S2) print $1,$2,T1,$8,T2,$14 } else { print $1,$2,T1,$8,$9,$10 } } 

Вы можете сделать это с помощью GNU sed:

convert_date.sed

 : a s/(([A-Za-z]{3} ){2}[0-9]{1,2} ([0-9]{2}:){2}[0-9]{2} [0-9]{4})(.*)/\n\4\n\1/ h s/.*\n// s/^/date -d "/ s/$/" +%s/e G s/([^\n]+)\n([^\n]+)\n([^\n]+)\n.*/\2\1\3/ /([A-Za-z]{3} ){2}[0-9]{1,2} ([0-9]{2}:){2}[0-9]{2} [0-9]{4}/ta 

Выполните его следующим образом:

 sed -rf convert_date.sed infile 

Вывод:

 pablo tty8 1351770681 still logged in (unknown tty8 1351770657 - 1351770681 (00:00) pablo tty2 1351770639 still logged in pablo tty7 1351770585 - 1351770656 (00:01) (unknown tty7 1351769672 - 1351770585 (00:15) 

объяснение

Сначала это может показаться немного сложным, но идея не такая уж сложная. Это регулярное выражение ([A-Za-z]{3} ){2}[0-9]{1,2} ([0-9]{2}:){2}[0-9]{2} [0-9]{4} , который встречается в первой замене и в конце условного, соответствует типу даты, используемому во вводе, он фиксирует и изолирует дату. Окружающие биты хранятся в пространстве удержания, а date -d запускается на захваченную дату. Наконец, все биты собираются в пространстве шаблонов и реорганизуются в правильный порядок.

Условие в конце повторяет процесс, если какие-либо даты остаются в пространстве шаблонов.

С perl и его модулем Date::Manip :

 perl -MDate::Manip -pe ' s/\w{3} \w{3} +\d+ \d\d:\d\d:\d\d \d+/ UnixDate ParseDate("$&"),"%s"/ge' 

Решение Perl, предоставляемое Stephane, требует неявного модуля Perl. Можно использовать основной модуль (начиная с 5.10), Time :: Piece , аналогично:

 #!/usr/bin/env perl use strict; use warnings; use Time::Piece; my $t = Time::Piece->new; while (<>) { s{\w{3}\s(\w{3}\s\d{1,2}\s\d\d:\d\d:\d\d\s\d{4})} {$t=Time::Piece->strptime($1,"%b %d %H:%M:%S %Y"); sprintf "%s",$t->epoch}ge; print; } 
  • tune2fs: какой часовой пояс - это дата, в которой она создана, и можно ли ее изменить?
  • Создайте каталог с датой
  • Как поставить отметку времени с помощью: wget --output-file =
  • Определение разницы в датах в формате «% Y% m% d% H% M% S»
  • Выделите сегодня в Mac
  • Как извлечь дату и рассчитать, находится ли она в течение «х» дней с сегодняшнего дня?
  • Получить последнюю минуту из строк из списка
  • Усечение точности даты
  • solaris awk проблемы с датой и заявлениями
  • Сценарий с использованием пользовательского ввода для расчета старой даты
  • Как я могу удалить все файлы в папку, к которой не было доступа за определенное время?
  • Interesting Posts

    Linux / UNIX для более старого (Pentium 4) ноутбука

    Как удалить языковой перевод из apt-get update?

    Emacs sync w / Календарь и контакты Google?

    Застрял в цикле регистрации после редактирования / etc / profile

    Приложение Командные ярлыки не работают глобально

    используйте net instread cdrom. linux, установка aptitude

    Извлечь строки на основе диапазона в другом файле

    Какие темы относятся к темам под контролем в темах корицы?

    Двухфакторная аутентификация SFTP

    Для подключения / dev / mapper / docker требуется аутентификация

    Параллелизировать рекурсивное удаление с помощью find

    Могут ли fstab опции uid и gid быть имя группы пользователей или они должны быть числовыми?

    Возможно ли установить GRUB с установочного диска Debian, чтобы также поддерживать существующую установку WinXp / Win8.1?

    Как изменить изображение иконки dekstop на Cinnamon?

    Необходимо преобразовать байты в GB, MB, KB в нормальный десятичный формат

    Linux и Unix - лучшая ОС в мире.