Intereting Posts
Как я могу сделать мой вызов .bashrc для shopt -s autocd зависеть от версии bash? Shell Script – как scp на удаленный сервер и загружать файлы и защищать пароль Извлеките только определенный файл из архива с zip-файлом в заданный каталог Является непривилегированным LXC, где сам пользователь хоста отображается на 0 менее безопасным из того, где одна из его субад отображается на 0, и почему? Правильно ли время системы, когда дата не установлена? Удаление пространства в начале переменных данных Проверьте, исправлен ли файл или папка Изменение значения systemd.service TimeoutSec на «бесконечность» не влияет Синтаксическая ошибка в точке с запятой в сценарии оболочки Любой способ показать каждый шаг во время обработки команды? Это имя моего хоста и DNS-домен? Деактивировать новую поддержку собственных жестов в GNOME 3.14 GNU Parallel: как сохранить результаты нескольких команд для переменной? Установить порты для подключения ssh к удаленному малине Pi При удалении файла под OpenSolaris нет места на устройстве

Фильтровать большие наборы данных в датах с командной строкой

У меня есть огромные наборы данных, которые состоят из значений, разделенных вкладкой, которые хранятся в строках. Пример строки выглядит так:

Dec 4 14:37:36.381651 algorc1 [27751:l@27932]/error: [] - [T0000A124M5] Didn't receive message! 

Я хочу отфильтровать все помехи до определенного времени в определенную дату.

Мои мысли таковы:

 grep <file> | select everything in first column larger than date | select everything in second column larger than time 

Я просто не знаю, как я могу выбрать по столбцу, и я не знаю о более крупных и меньших датах и ​​времени.

Поэтому я не знаю, что много ;-).

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

 sed -n '/Dec 4 14:37:36.381651/,/Dec 5 14:32:36.391572/' filename 

Вы не можете округлить эти время / даты до значений, которые не существуют. Например:

 sed -n '/Dec 4 14:30:00.000000/,/Dec 5 14:29:59.999999/' filename 

не будет работать, если указанное время не было в журнале.


Если вы хотите отфильтровать между двумя произвольными временем / датами, которые не находятся в журнале, то awk может помочь:

 awk 'BEGIN {FS=":| +"} {current = mktime("2014 "c($1)" "$2" "$3" "$4" "$5); if (current >= mktime ("2014 12 04 14 30 0") && current <= mktime("2014 12 05 14 29 59")) {print $0 }} function c(s){return(sprintf("%02d\n",(match("JanFebMarAprMayJunJulAugSepOctNovDec",$1)+2)/3)) }' filename 

Выбранное время / даты указано в формате ГГГ ММ ДД ЧЧ ММ СС. Вы также заметите, что год жестко закодирован, поскольку ваши журналы не содержат год – я предположил, что в этом году.

Вышеуказанный однострочный, но лучше отформатированный и с комментариями:

 #!/usr/bin/awk -f BEGIN { # Split line into fields using colon or spaces FS=":| +" } { # Generate the timestamp of the current line from the first 5 fields. # Use the function c(), defined below, to convert 3 letter months to numerical current = mktime("2014 "c($1)" "$2" "$3" "$4" "$5); # If the timestamp of the current line is between two specified # timestamps then print the whole line if (current >= mktime ("2014 12 08 15 0 0") && current <= mktime("2014 12 08 16 05 00")) {print $0 } } function c(s) { # Function to convert three letter month to numerical # If s == Jan then returns 1. If s == Aug, returns 8 return(sprintf("%02d\n",(match("JanFebMarAprMayJunJulAugSepOctNovDec",$1)+2)/3)) } 

Одно решение, конвертирующее дату в эпоху:

 while read month dm hour rest; do d=$(date -d"$month $dm $hour" "+%m%d%H%M%S") echo "$d $rest" done < file | awk '$1 < 1204143737' # print all lines before this date