Извлеките определенные строки набора, соответствующие правилу

В моей системе (Linux Mint Выпуск Debian) это, кажется, прибывает из libpam-modules. Найти это мной сначала grep для /etc/environment в /var/lib/dpkg/info/:

grep -C 5 "/etc/environment" /var/lib/dpkg/info/*

Это показывает что файл /var/lib/dpkg/info/libpam-modules:amd64.postinst содержит эти строки:

if dpkg --compare-versions "$2" lt 0.99.9.0-1 && ! [ -f /etc/environment ]
then
    touch /etc/environment
fi

Это вызовет пустое (простой touch) /etc/environment файл, который будет создан, если это не существует и если версия того, что дано сценарию как его второй аргумент ($2) меньше, чем 0.99.9.0-1.

3
06.09.2014, 07:50
2 ответа

Предполагая, что ваш файл журнала называется файл журнала , вот решение awk с примером вывода:

$ awk '/RINGING/,/CLOSE/ {if (/30 30/){f=1}; a=a"\n"$0} f==0 && /CLOSE/ {print a} /CLOSE/{a="";f=0}' logfile    

313782 Aug 19 18:37:04.925: <DATA>  RINGING|254|01136097645|5950|$hostIp|$size  |$data
313783 Aug 19 18:37:05.262: <DATA>  TRAINING|254|01136097645|5950|$hostIp|$size  |$data
313784 Aug 19 18:37:09.028: <DATA>  OUT  |254|01136097645|5950|$hostIp|2 bytes  |30 93
313785 Aug 19 18:37:09.705: <DATA>  IN   |254|01136097645|5950|$hostIp|4 bytes  |30 73 F9 F8
313786 Aug 19 18:37:18.532: <DATA>  IN   |254|01136097645|5950|$hostIp|336 bytes  |30 10 60 00 06 00 00 6F 12 00
313788 Aug 19 18:37:20.898: <DATA>  TRAINING|254|01136097645|5950|$hostIp|$size  |$data
313789 Aug 19 18:37:22.006: <DATA>  CLOSE|254|01136097645|5950|$hostIp|$size  |$data

Пояснение

Взятие каждой команды awk по очереди:

  • / RINGING /, / CLOSE / {if (/ 30 30 /) {f = 1}; a = a "\ n" $ 0}

    Выражение / RINGING /, / CLOSE / является диапазоном: оно указывает, что эта команда применяется только к группам строк. Группа запускается, когда встречается строка, содержащая текст ЗВОНОК . Группа заканчивается, когда встречается строка, содержащая текст ЗАКРЫТЬ . Для любой строки в такой группе выполняются команды в фигурных скобках. Первый из них устанавливает флаг f в единицу, если строка содержит 30 30 . Вторая команда добавляет текущую строку к переменной a .

  • f == 0 && / CLOSE / {print a}

    Командам в фигурных скобках здесь предшествуют два условия, и они складываются вместе. Первое условие указывает, что флаг f равен нулю (что означает, что 30 30 не был найден в этой группе), а второе указывает, что эта строка содержит текст CLOSE ]. Если оба этих условия соблюдены, печатается группа строк, хранящаяся в переменной a .

  • / CLOSE / {a = ""; f = 0}

    Наконец, в любой строке, содержащей текст CLOSE , переменная a сбрасывается до пустой строки. и флаг f устанавливается в ноль. Когда это будет сделано, код готов к запуску на следующей группе строк, если таковая будет.

4
27.01.2020, 21:14

Может быть возможен с использованием совместимого Perl Regex (PCRE) Например

pcregrep -M '^.*?RINGING(?(?!30 30)(?s).)+?CLOSE.*?$' file

или

grep -zPo '^.*?RINGING(?(?!30 30)(?s).)+?CLOSE.*?$' file

Альтернативно, с использованием более выразительного разделителя записи GNU AWK

gawk -vRS="CLOSE[^\n]*\n" -vORS= '!/30 30/ {print; print RT}' file
2
27.01.2020, 21:14

Теги

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