Печать Sed с оцененной командой даты на обратной ссылке - PullRequest
2 голосов
/ 31 мая 2011

У меня есть файл (как это часто бывает) с датами в * nix времени в секундах с начала эпохи, за которым следует сообщение и последнее поле «нить», которое я хочу выбрать. Все разделены знаком '|' как экспортировано из базы данных sqlite ...

* 1003 например *

1306003700|SENT|21
1277237887|SENT|119
1274345263|SENT|115
1261168663|RECV|21
1306832459|SENT|80
1306835346|RECV|80

В принципе, я могу использовать sed достаточно легко, чтобы выбирать и печатать строки, которые соответствуют полю "нить", и печатать соответствующее время с сообщениями, таким образом:

> cat file | sed -n "s/^\([0-9]*\)\|\(.*\)\|80$/\1 : \2/p"
1306832459 : SENT
1306835346 : RECV

Но что я действительно хочу сделать, так это передать поле времени командой unix date, поэтому:

> cat file | sed -n "s/^\([0-9]*\)\|\(.*\)\|80$/`date -r \1` : \2/p"

Но это, похоже, не работает - хотя, кажется, это принимает. Он просто печатает ту же (начало эпохи) дату:

Thu  1 Jan 1970 01:00:01 BST : SENT
Thu  1 Jan 1970 01:00:01 BST : RECV

Как / как я могу оценить / интерполировать обратную ссылку \ 1 на команду даты?

Может быть, sed не способ сопоставить эти строки (и отформатировать вывод за один раз) ...

Ответы [ 7 ]

4 голосов
/ 31 мая 2011

awk идеально подходит для этого.

awk -F"|" '$3 == '80' { print system("date -r " $1), ":", $2 }' myfile.txt

Должно работать (хотя не могу гарантировать правильность системного вызова, не проверял его)

3 голосов
/ 31 мая 2011

Этот чистый bash

wanted=80
(IFS=\|; while read sec message thread
do
        [[ $thread == $wanted ]] && echo $(date -r $sec) : $message
done) < datafile.txt

print

Tue May 31 11:00:59 CEST 2011 : SENT
Tue May 31 11:49:06 CEST 2011 : RECV

Вы можете заключать переменные в "" для большей безопасности ...

1 голос
/ 18 марта 2012

Это может работать для вас:

 sed -n 's/^\([0-9]*\)|\(.*\)|80$/echo "$(date -d @\1) : \2"/p' file | sh

или если у вас есть GNU sed:

 sed -n 's/^\([0-9]*\)|\(.*\)|80$/echo "$(date -d @\1) : \2"/ep' file
1 голос
/ 31 мая 2011

Perl удобен здесь:

perl -MPOSIX -F'\|' -lane '
    next unless $F[2] == "80";
    print(strftime("%Y-%m-%d %T", localtime $F[0]), " : ", $F[1])
' input.file
0 голосов
/ 22 мая 2016

Вдохновленный ответом Рэйфа выше:

awk -F"|" '$3 == '80' { system("date -d @" $1 " | tr -d \"\n\""); print " :", $2 }' myfile.txt

Для моей версии даты кажется, что -d является аргументом, а не -r, и что для него требуется ведущий @.Другое изменение здесь - это то, что системный вызов выполняется (поэтому date фактически выполняет печать, перевод строки и все - отсюда tr) и возвращает код выхода.Нам не нужно печатать код выхода (0), поэтому мы перемещаем вызов system вне любых awk print s.

0 голосов
/ 31 мая 2011

Команда date будет выполнена перед командой sed.

Для этой работы проще всего использовать perl или python, иначе вы можете использовать какой-то цикл bash.

0 голосов
/ 31 мая 2011

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

$(awk -F'|' '/80$/{printf("echo $(date -d @%s) : %s;",$1,$2);}' /path/to/file)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...