unix ггггммддччммсс преобразование формата в определенный формат даты - PullRequest
0 голосов
/ 13 февраля 2019

Работает скрипт bash, который выводит имена папок с добавлением времени logs_debug_20190213043348.Мне нужно иметь возможность извлечь дату в удобочитаемый формат yyyy.mm.dd.hh.mm.ss, а также может быть преобразован в часовой пояс GMT.Я использую метод ниже для извлечения.

echo "$ {folder ## * _}" |awk '{print substr ($ 0,1,4) "." substr ($ 0,5,2) "." substr ($ 0,7,2) "." substr ($ 0,9,6)}'

Есть ли лучший способ напечатать вывод без написания сложных сценариев оболочки?

Ответы [ 2 ]

0 голосов
/ 13 февраля 2019

Внутренние функции преобразования строк слишком ограничены, поэтому мы используем sed и tr при необходимости.

## The "readable" format yyyy.mm.dd.hh.mm.ss isn’t understood by date. 
## yyyy-mm-dd hh:mm:ss is. So we first produce the latter.

# Note how to extract the last 14 characters of ${folder} and that, since
# we know (or should have checked somewhere else) that they are all digits,
# we match them with a simple dot instead of the more precise but less
# readable [0-9] or [[:digit:]]
# -E selects regexp dialect where grouping is done with simple () with no
# backslashes.
d="$(sed -Ee's/(....)(..)(..)(..)(..)(..)/\1-\2-\3 \4:\5:\6/'<<<"${folder:(-14)}")"

# Print the UTF date (for Linux and other systems with GNU date)
date -u -d "$d"

# Convert to your preferred "readable" format  
# echo "${d//[: -]/.}" would have the same effect, avoiding tr
tr ': -' '.'<<<"$d"

Для систем с BSD date (особенно MacOS) используйте

date -juf'%Y-%m-%d %H:%M:%S' "$d"

вместо приведенной выше команды date.Конечно, в этом случае самый простой способ будет:

# Convert to readable
d="$(sed -Ee's/(....)(..)(..)(..)(..)(..)/\1.\2.\3.\4.\5.\6/'<<<"${folder:(-14)}")"
# Convert to UTF
date -juf'%Y.%m.%d.%H.%M.%S' "$d"
0 голосов
/ 13 февраля 2019

Вот конвейер, который делает то, что вы хотите.Это, конечно, не просто, но с учетом каждого компонента это можно понять:

echo "20190213043348" | \
sed -e 's/\([[:digit:]]\{4\}\)\([[:digit:]]\{2\}\)\([[:digit:]]\{2\}\)\([[:digit:]]\{2\}\)\([[:digit:]]\{2\}\)\([[:digit:]]\{2\}\)/\1-\2-\3 \4:\5:\6/' | \
xargs -d '\n' date -d | \
xargs -d '\n' date -u -d

Первая строка просто печатает строку даты, чтобы sed мог отформатировать ее (чтобы ее можно было легко изменить, чтобы она соответствовалакак вы передаете строку).

Вторая строка с sed преобразует строку из заданного вами формата во что-то вроде этого, которое может быть проанализировано с помощью date: 2019-02-13 04:33:48

Затем мы передаем дату в date, используя xargs, и она форматирует ее с указанием часового пояса устройства, на котором выполняется скрипт (в моем случае CST): Wed Feb 13 04:33:48 CST 2019

Последняя строка преобразует строку даты, заданную первым вызовом date, в UTC время, а не застревает по местному времени: Wed Feb 13 10:33:48 UTC 2019

Если вы хотите, чтобы она была в другом формате, вы можете изменитьокончательный вызов date с использованием аргумента +FORMAT.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...