Преобразование столбца временных меток эпохи unix в каждой строке с помощью sed или awk

В разных вариантах Unix используются разные утилиты. Есть кое-что общее (например, все они имеют утилиту df ), но некоторые детали различаются (например, точный формат вывода и доступность определенных параметров, таких как -h ). Linux поставляется с GNU coreutils , который имеет более удобные для пользователя параметры, чем те же самые утилиты в большинстве других вариантов, например, параметр -h .

Вы можете установить GNU coreutils во многих других вариантах Unix, но я не знаю о NCR, это не совсем современно или широко распространено.

Если NCR не слишком древний, вы можете по крайней мере использовать все параметры, стандартизированные POSIX , который для df включает -k для отображения в кБ, а не 512Б, и -P для отображения тех же столбцов, что и в GNU / Linux df .

Чтобы узнать, какие параметры поддерживает ваша версия df , используйте man df .

Для команд администрирования полезен Rosetta Stone для Unix . Я не знаю аналогичного документа для пользовательских команд, но спецификация POSIX / Single Unix дает представление.

1
17.11.2018, 22:41
3 ответа

Или с вашей оболочкой:

while read timestamp pid ip port; do
  echo "$(date -d @$timestamp)|$pid|$ip|$port"
done <yourfile
1
27.01.2020, 23:14

Вы можете использовать awk-программу следующим образом:

awk '{ print strftime("%c",$1)"|" $2"|"$3"|"$4 }' file

ядром является использование функции strftime для преобразования эпохи в формат даты

Вот результат:

#awk '{ print strftime("%c",$1)"|" $2"|"$3"|"$4 }' file
Sun Jan 22 10:12:26 2006|180900|61.153.158.197|1409
Sun Jan 22 10:12:38 2006|181622|61.153.158.197|1409
Sun Jan 22 10:22:38 2006|180026|221.226.124.114|1374
Sun Jan 22 10:23:22 2006|179485|121.13.128.132|1409

P.S. Или вы можете использовать неявный разделитель вывода:

awk  'BEGIN { OFS="|"} {$1= strftime("%c",$1) }1' file
6
27.01.2020, 23:14

Используя то, что вы уже знаете:

  • GNU дата может преобразовать метку времени в отформатированную дату, задав ей @timestamp.
  • Замена пробелов на | даст вам желаемый результат.

К этому мы добавляем

  • GNU дата может работать с файлом, конвертируя даты в одном пакете.

Для пакетного преобразования дат с помощью GNU date мы должны извлечь метки времени и добавить к ним префикс @:

$ sed 's/^\([^ ]*\).*$/@\1/' data.in
@1137921146.499
@1137921158.698
@1137921758.163
@1137921802.016

Выражение sed заменяет каждую строку на первое поле, разделенное пробелами, с префиксом @.

С bashksh93 или любой оболочкой, которая понимает подстановки процессов):

$ date -f <( sed 's/^\([^ ]*\).*$/@\1/' data.in )
Sun Jan 22 10:12:26 CET 2006
Sun Jan 22 10:12:38 CET 2006
Sun Jan 22 10:22:38 CET 2006
Sun Jan 22 10:23:22 CET 2006

Затем нам нужно взять другие поля входных данных и заменить разделители:

$ cut -d ' ' -f 2- data.in | tr ' ' '|'
180900|61.153.158.197|1409
181622|61.153.158.197|1409
180026|221.226.124.114|1374
179485|121.13.128.132|1409

Затем мы вставляем эти две вещи вместе с | в качестве разделителя:

$ paste -d '|' <( date -f <( sed 's/^\([^ ]*\).*$/@\1/' data.in ) ) <( cut -d ' ' -f 2- data.in | tr ' ' '|' )
Sun Jan 22 10:12:26 CET 2006|180900|61.153.158.197|1409
Sun Jan 22 10:12:38 CET 2006|181622|61.153.158.197|1409
Sun Jan 22 10:22:38 CET 2006|180026|221.226.124.114|1374
Sun Jan 22 10:23:22 CET 2006|179485|121.13.128.132|1409
2
27.01.2020, 23:14

Теги

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