Лучший способ увеличить числа в одной строке в Linux

Лучший способ увеличить числа в одной строке в Linux

У меня есть одна строка со множеством записей, среди которых есть и время.

 ('DEFAULT',17,NULL,'2014-07-14 10:30:00','Something','2014-07-14 06:30:00',1),('DEFAULT',26,NULL,'2014-07-14 12:00:00','Something2,'2014-07-14 11:00:00',1),...

Я хотел бы увеличивать каждый раз на несколько часов. в формате 24 ч. Например, 10:30:00это станет 15:30:00.

Какой универсальный инструмент лучше всего подойдет для этой работы? Я думаю о:

  1. системные утилиты типа awk, sed.. и что-то еще, чего я не знаю

  2. vim

  3. скриптовые языки, такие как bashили python`

Каков был бы канонический способ сделать это?

решение1

Просто для уточнения:

vim— системная утилита (текстовый редактор) в большинстве систем *nix. awk, sed, и bash— это языки (или инструменты, в зависимости от контекста), которые можно использовать для анализа и изменения текста.

Для чего вам нужно увеличить время и как часто вам нужно будет его увеличивать? Это влияет на то, какие инструменты вы захотите использовать. В любом случае, это многоэтапная работа, ПРЕДПОЛАГАЯ, ЧТО ЭТО НЕ SQL:

  1. Сначала вы сопоставляете частичные строки внутри строки. Вы можете использовать awk, sed, или grep -e, с регулярным выражением, чтобы вытащить эти подстроки.

  2. Когда у вас есть эти значения, вы преобразуете их в целые числа (или, если вы используете более полный язык, например, Python, вы можете преобразовать их в значения datetime с помощью библиотеки). Вам придется выполнить необходимые математические вычисления (и проверку, если применимо), чтобы изменить эти значения.

  3. Наконец, вы добавите замененные значения в строку и сохраните измененный файл.

Честно говоря, это выглядит так sql, поэтому было бы гораздо проще использоватьвстроенные инструментына этом языке, чтобы изменить эти значения.

решение2

Есть несколько хороших советов вэтот ответпредлагая путь наименьшего сопротивления с использованием языка сценариев, такого как Perl, Python, Ruby и т. д., который позволяет смешивать математические операции и операции сопоставления.

Вот быстрый способ с помощью Perl:

$ echo '2014-12-05 10:00:10, 1234, 2015-02-01 09:12:24' | perl -pe \
    's/(\d{4}-\d{2}-\d{2} )(\d{2})(:\d{2}:\d{2})/join("",$1,$2+3,$3)/eg'
2014-12-05 13:00:10, 1234, 2015-02-01 12:12:24
$

В этом упрощенном примере класс символов цифры ( \d), за которым следует индикатор повторения (например {2}), используется для захвата позиционных компонентов даты, и мы слепо выполняем арифметические действия в поле часов. Этот тип решения подходит только в том случае, если вы достаточно хорошо знаете свои данные, чтобы гарантировать, что упрощенная арифметика в поле часов не приведет к смещению дня.

Возвращаясь к этой проблеме для решения корректной арифметики даты/времени при переполнении поля часов, как подсказал @Lieven, Time::Pieceможно использовать основной модуль Perl (Perl>5.8):

$ echo '2014-12-05 22:00:00, 1234, 2015-02-01 09:12:24' | \
    perl -MTime::Piece -pe \
        's/(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})/( \
            Time::Piece->strptime($1, "%Y-%m-%d %T") \
            + (60*60*3))->strftime("%Y-%m-%d %T")/eg'
2014-12-06 01:00:00, 1234, 2015-02-01 12:12:24
$

Этот пример ввода был обновлен, чтобы показать изящную обработку значений часов, переходящих на следующий день. Он загружает Time::Pieceмодуль в командной строке, сопоставляет дату и время с вводом, преобразует в Time::Pieceобъекты для выполнения арифметических операций с датой и временем, а затем преобразует обратно в нужный формат вывода.

Связанный контент