
Я пытаюсь извлечь данные между двумя совпадающими шаблонами, только если содержимое не пустое, и у меня возникают проблемы с этим:
вот пример:
==============================
Queue Manager is : MQ73PCRTB2
==============================
==============================
Queue Manager is : MQ73PCSH01
==============================
_________________________________
Current instances are over 80% of max instnaces allowed for the channel WAS.P2QG2E00.SVRC
Max Instances allowed is 100
Current Instances running is 100
==============================
Queue Manager is : MQ73PCSH02
==============================
_________________________________
Current instances are over 80% of max instnaces allowed for the channel WAS.P2QG2E00.SVRC
Max Instances allowed is 100
Current Instances running is 100
==============================
Queue Manager is : MQ73PCSHA1
==============================
==============================
Queue Manager is : MQ73PCSHA2
==============================
В результате я хочу увидеть следующее:
==============================
Queue Manager is : MQ73PCSH01
==============================
_________________________________
Current instances are over 80% of max instnaces allowed for the channel WAS.P2QG2E00.SVRC
Max Instances allowed is 100
Current Instances running is 100
==============================
Queue Manager is : MQ73PCSH02
==============================
_________________________________
Current instances are over 80% of max instnaces allowed for the channel WAS.P2QG2E00.SVRC
Max Instances allowed is 100
Current Instances running is 100
Я знаю, что нужно извлекать строки до и после совпадающего текста, извлекать все, что находится между совпадающими шаблонами, но хочу знать, как вывести все, что находится между совпадающими шаблонами, только если данные не пустые.
Вот что я попробовал и что не сработало:
grep -zPo '(?s)Queue(?:.(?!</Queue))*?\Current*?</Queue'
Исходный текстовый файл создается другим скриптом.
Между совпадающим шаблоном «Очередь» может быть более 3 строк в данных.
решение1
Вы можете попробовать вот так
sed '/Queue/{N;$d;N;$d;N;/==$/d}' infile
Это просто подтягивает следующие три строки, когда строка соответствует Queue
. Если пространство шаблона заканчивается разделителем 1 , он удаляет его (или если 2 , то 1-я или 2-я подтянутая строка является последней во входных данных).
Если другие строки могут заканчиваться последовательными =
знаками, вы должны заменить ==$
в регулярном выражении на точное совпадение для разделителя, например=\{37\}$
1: Предполагается, что разделителем является строка, совпадающая с предыдущей ^[[:blank:]]*==*$
(поэтому нет конечных пробелов).
2: Поскольку содержимое вашего файла создается скриптом, файл всегда должен заканчиваться пустой строкой, поэтому sed должен проверять только то, является ли вторая извлеченная строка последней строкой в файле (чтобы определить, является ли последний блок пустым), но в вашем примере эта конечная строка отсутствует, поэтомуили...
решение2
BEGIN { RS="=====*\n" }
/Queue Manager/ {
manager = $0; next;
}
/[a-z]/ {
print RT manager RT $0;
}
Первое правило устанавливает разделитель записей в четыре или более знаков равенства. Второе правило отслеживает "заголовок", т.е. запись, содержащую строку "Queue Manager". Третье правило выводит заголовок и текущую запись, если запись содержит хотя бы одну строчную букву, т.е. не пуста.