Intereting Posts
SSH на сервер, используя билет обслуживания kerberos, который не является основным хозяином Проблемы с компиляцией Python 3.6.0+ в Qubes OS Debian Ubuntu: обрабатывает vfs-рабочий, беря все ресурсы процессора Как настроить SMTP с помощью postfix с пользователем и пройти Как поместить команду EOF в одну строку для выполнения нескольких команд оболочки Команда sed удалила все и оставила только слова между шаблонами? FFMPEG запускает видеофильтр и копирует только 1 stream субтитров Силовое разрешение экрана в Lubuntu Отправка файлов в каталоги с использованием сопоставления имен Редактирование файлов Adobe PageMaker (.pmd) в debian Американский Fuzzy Lop запускает тестовую программу как непривилегированный пользователь или в chroot Что означает: 0 означает в конфигурации vnc? Настройте приложения для запроса пользователя: пройдите через прокси-сервер Перемещение изображения qcow2 на физический жесткий диск В чем разница между прикрепленным и отсоединенным экраном?

Нужно преобразовать столбец timestamp unix epoch в каждую строку с помощью sed или awk

У меня есть файл со следующими входными примерными данными:

1137921146.499 180900 61.153.158.197 1409 1137921158.698 181622 61.153.158.197 1409 1137921758.163 180026 221.226.124.114 1374 1137921802.016 179485 121.13.128.132 1409 

1-й столбец – это временная отметка эпохи unix, которую мне нужно преобразовать в человеческий читаемый формат, плюс я хочу, чтобы данные были разделены следующим образом

 Sun Jan 22 01:12:26 PST 2006|180900|61.153.158.197|1409 Sun Jan 22 01:12:38 PST 2006|181622|61.153.158.19|1409 

Я попытался добавить разделители, используя sed '/ {1,} / | / g' и преобразовать дату с датой -d @ 1137921146.499. Но я не могу объединить их в одну команду.

Может ли кто-нибудь помочь мне здесь?

Вы можете использовать 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 

PS Вы можете использовать неявный выходной разделитель:

 awk 'BEGIN { OFS="|"} {$1= strftime("%c",$1) }1' file 

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

 while read timestamp pid ip port; do echo "$(date -d @$timestamp)|$pid|$ip|$port" done <yourfile 

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

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

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

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

Чтобы конвертировать даты с date GNU, нам нужно извлечь временные метки и префикс их с помощью @ :

 $ 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