Корректируйте информацию о дате и времени внутри нескольких текстовых файлов автоматически из командной строки

У меня есть папка с несколькими текстовыми файлами, содержимое которых выглядит примерно так:

text text
more text
Date: Thu, 31 Dec 2015 23:53:51 +0000 (UTC)
more text
some more

Я хочу, чтобы эта дата и время были правильными в соответствии с моим часовым поясом (в моем случае, если он говорит « +0000 (UTC) «Я должен добавить 1 час для зимнего времени)

Таким образом, результатом должен быть тот же файл (с тем же именем файла или, если вы хотите,« fixeddate_originalfilename »), содержащий:

text text
more text
Date: Fri, 1 Jan 2016 00:53:51
more text
some more

Обратите внимание, что строка, которая должна быть отредактирована, начинается с «Date:» (который уникален, в текстовом файле нет другой «Date:») и заканчивается на «+0000 (UTC)». И он будет редактироваться только в том случае, если конец строки равен «+0000 (UTC)».

Среди тех файлов, с которыми у меня есть другие:

text text
text text
Date: Mon, 12 Oct 2015 23:07:29 +0200
text text
text text

Эти не нужно настраивать (на самом деле я бы хотел, чтобы «+0200» было удалено).

Эти исправления будут автоматически и периодически вноситься во все файлы, содержащиеся в «/ home / user / folder01» (например, я не перед этим компьютером). Я использую Ubuntu 15.04.

0
задан 16 October 2015 в 21:32

3 ответа

perl для удаления и awk для date часть. Замена foo с Вашим именем файла

perl -pe 's/^(Date:.*)\+[0-9]{4}$/$1/' foo | \
    awk -F'Date:' '/(UTC)/ {system("echo Date: $(date -d \""$2"\" +\"%a, %d %b %Y %H:%M:%S\") "); next} {print $0}'

Пример

cat dates

text text
more text
Date: Thu, 31 Dec 2015 23:53:51 +0000 (UTC)
more text
some more
text text
text text
Date: Mon, 12 Oct 2015 23:07:29 +0200
text text
text text
text text
more text
Date: Fri, 1 Jan 2016 01:53:51
more text
some more
perl -pe 's/^(Date:.*)\+[0-9]{4}$/$1/' dates | \
    awk -F'Date:' '/(UTC)/ {system("echo Date: $(date -d \""$2"\" +\"%a, %d %b %Y %H:%M:%S\") "); next} {print $0}'
text text
more text
Date: Fri, 01 Jan 2016 01:53:51
more text
some more
text text
text text
Date: Mon, 12 Oct 2015 23:07:29 
text text
text text
text text
more text
Date: Fri, 1 Jan 2016 01:53:51
more text
some more
0
ответ дан 17 October 2015 в 07:32
  • 1
    Можно ли добавить соответствующие детали того, как использовать tcpdump для достижения установленной цели? – Chai T. Rex 5 January 2017 в 07:38

Можно использовать GNU date преобразовать то время в Вашу зону местного времени.

 awk '/^Date:.*UTC/ {cmd="date -Rd \"" substr($0,6) "\""; cmd | getline new; close(cmd); $0="Date: " new} 1' file
text text
more text
Date: Fri, 01 Jan 2016 01:53:51 +0200
more text
some more

Если у Вас есть GNU awk, можно измениться оперативный все файлы в использовании текущего каталога:

gawk -i inplace '/^Date:.*UTC/ {cmd="date -Rd \"" substr($0,6) "\""; cmd | getline new; close(cmd); $0="Date: " new} 1' *

Без GNU awk, используйте:

for f in *
do
    awk '/^Date:.*UTC/ {cmd="date -Rd \"" substr($0,6) "\""; cmd | getline new; close(cmd); $0="Date: " new} 1' "$f" >tmp && mv tmp "$f"
done

Как это работает

  • -i inplace

    Это говорит GNU awk изменять файлы на месте. Это требует современного GNU awk. При использовании awk Mike's то используйте вместо этого цикл удара как показано выше.

  • /^Date:.*UTC/ {cmd="date -Rd \"" substr($0,6) "\""; cmd | getline new; close(cmd); $0="Date: " new}

    Это выбирает строки, которые запускаются с Date: и содержите UTC на той же строке. Для тех строк, команды date -Rd выполняется со стороны строки, содержащей дату. Результат хранится в переменной new. Затем текущая строка, обозначенная $0 в awk, заменяется одним с новой датой.

  • 1

    Это - загадочное сокращение awk от печати строки.

Несколько выравнивают версию GNU

Если Вы предпочитаете свои сценарии, распространенные по нескольким строкам:

gawk -i inplace '

/^Date:.*UTC/ {
    cmd="date -Rd \"" substr($0,6) "\""; cmd | getline new
    close(cmd)
    $0="Date: " new
}

1
' file

Некоторые улучшения (версия не-GNU)

  1. Код выше ищет строки, запускающиеся с Date: это также содержит буквы UTC. Это, кажется мне достаточно хорошо. Вопрос, однако, спрашивает больше специально для строк, которые запускаются Date: и конец с +0000 (UTC).

  2. Вопрос также просит устранять запаздывание +0200 от линий перемены даты не-UTC.

Добавляя эти два улучшения, код становится:

for f in *
do
    awk '/Date: .* [+]0200$/{sub(/ [+]0200$/,"")} /^Date: .* [+]0000 [(]UTC[)]$/ {cmd="date -Rd \"" substr($0,6) "\""; cmd | getline new; close(cmd); $0="Date: " new} 1' "$f" >tmp && mv tmp "$f"
done

Этот код является более точным, но также и более дотошным. Например, этот код настаивает что конец строки с +0000 (UTC) прежде чем это изменит его. Следовательно, строки с запаздывающим пробелом, который может быть невидимым в Вашем редакторе, не будут изменены. Хорошо ли это или не является чем-то, чтобы Вы решили.

2
ответ дан 17 October 2015 в 07:32

Использование Perl:

perl -pe 's/Date: (.* \+0000 \(UTC\))/$1/?$_="Date: ".`LC_TIME=en_US.UTF-8 date -d "$_" "+%a, %d %b %Y %T"`:s/(Date:.*) \+[0-9]{4}/$1/' in
  • Если s/Date: (.* \+0000 \(UTC\))/$1/ замена, которая заменяет целую строку разделом после Date:, мог быть сделан, печать Date: сопровождаемый выводом LC_TIME=en_US.UTF-8 date -d "$_" "+%a, %d %b %Y %T", который преобразовывает часть, которой заменяют, в использование зоны текущего времени LC_TIME значение en_US.UTF-8; иначе, если s/(Date:.*) \+[0-9]{4}/$1/ замена, которая заменяет целую строку разделом прежде +NNNN, мог быть сделан, печатает часть, которой заменяют; если никакая замена не могла бы быть сделана, печатает целую строку.

Это означает что ток LC_TIME значение установлено к en_US.UTF-8 (или эквивалентный) уже, LC_TIME=en_US.UTF-8 часть безопасна быть отброшенной:

perl -pe 's/Date: (.* \+0000 \(UTC\))/$1/?$_="Date: ".`date -d "$_" "+%a, %d %b %Y %T"`:s/(Date:.*) \+[0-9]{4}/$1/' in
% cat in
line
Date: Thu, 31 Dec 2015 23:53:51 +0000 (UTC)
Date: Mon, 12 Oct 2015 23:07:29 +0200
% perl -pe 's/Date: (.* \+0000 \(UTC\))/$1/?$_="Date: ".`LC_TIME=en_US.UTF-8 date -d "$_" "+%a, %d %b %Y %T"`:s/(Date:.*) \+[0-9]{4}/$1/' in
line
Date: Fri, 01 Jan 2016 00:53:51
Date: Mon, 12 Oct 2015 23:07:29

Чтобы отредактировать оперативный файл и применить это к нескольким файлам, можно добавить -i переключатель и передача * вместо имени файла:

% cat in
line
Date: Thu, 31 Dec 2015 23:53:51 +0000 (UTC)
Date: Mon, 12 Oct 2015 23:07:29 +0200
% cat in1
line
Date: Thu, 31 Dec 2015 23:53:51 +0000 (UTC)
Date: Mon, 12 Oct 2015 23:07:29 +0200
user@user-X550CL ~/tmp % perl -i -pe 's/Date: (.* \+0000 \(UTC\))/$1/?$_="Date: ".`LC_TIME=en_US.UTF-8 date -d "$_" "+%a, %d %b %Y %T"`:s/(Date:.*) \+[0-9]{4}/$1/' *
user@user-X550CL ~/tmp % cat in
line
Date: Fri, 01 Jan 2016 00:53:51
Date: Mon, 12 Oct 2015 23:07:29
user@user-X550CL ~/tmp % cat in1
line
Date: Fri, 01 Jan 2016 00:53:51
Date: Mon, 12 Oct 2015 23:07:29
0
ответ дан 17 October 2015 в 07:32
  • 1
    Это было бы интересно, но если пользователь can' t устанавливают обновления, он can' t устанавливают другое программное обеспечение (от repos) также. Установка всего при использовании другой сети должна работать все же. –  5 January 2017 в 06:40

Другие вопросы по тегам:

Похожие вопросы: