2016-07-20 3 views
0

У меня есть файл, который имеет несколько строк, имеющие следующую структуру:Регулярного выражения для нескольких линий с отрицанием

Text line1: xxxx 
Text line2: x 
OS: "MacOS" 
NotOS: "Linux" 
Text line3: 
ID: 12345 

ИЛИ

Text line1: xxxx 
Text line2: x 
OS: "MacOS|Linux|Red Hat|Windows|Ubuntu|CentOS|Fedora" 
NotOS: "HP-UX" 
Text line3: 
ID: 12345 

Я ищу, чтобы получить все идентификаторы, которые имеют «CentOS "в поле ОС, но без" Linux "в поле NotOS. Я использовал следующее, который работает для меня какой-то степени, но не полностью:

grep -n 'OS\:.*[c|C]ent[o|O][s|S][\S+\n\r\s]+VulnID:' filename |\ 
grep -v '[L|l][I|i][N|n][U|u][X|x]|Amazon|Amazon Linux' 

Он стремится вернуть это:

15386:OS:    "Linux|AIX|Solaris|VMware|FreeBSD|IRIX|NetBSD|OpenBSD|BSD|Fedora|Ubuntu|Red.*Hat|CentOS|OpenSuSE|SuSE|MacOS|Oracle Enterprise Linux|HP-UX" 
15404:OS: "SuSE|Linux|AIX|BSD|CentOS|Solaris|HP-UX" 
15527:NotOS: "(Unknown|CentOS|Red Hat|Ubuntu|Oracle Enterprise Linux|Debian|Fedora|AIX|SuSE|Solaris)" 
15537:NotOS: "(Unknown|CentOS|Red Hat|Ubuntu|Oracle Enterprise Linux|Debian|Fedora|AIX|SuSE|Solaris)" 
15705:OS:    "Solaris|Linux|CentOS" 

где первые цифры номера строк, но это обыкновение возвращать текст с "ID:"

Как это сделать?

+0

Используйте '-i' для нечувствительности к регистру, поэтому вам не нужно писать' [c | C] '. Кроме того, вы не должны ставить '|' там, это должно быть просто '[cC]'. – Barmar

+0

Спасибо, Бармар! Я новичок, только начинаю с моего Linux-путешествия. – Metahuman

ответ

2

Держите это просто, просто использовать AWK:

$ awk -F': ' '{m[$1]=tolower($2)} $1=="ID" && m["OS"]~/centos/ && m["NotOS"]!~/linux/' file 
ID: 12345 

или если вы просто хотите номер:

$ awk -F': ' '{m[$1]=tolower($2)} $1=="ID" && m["OS"]~/centos/ && m["NotOS"]!~/linux/{print $2}' file 
12345 

выше был работать на этом файле:

$ cat file 
Text line1: xxxx 
Text line2: x 
OS: "MacOS" 
NotOS: "Linux" 
Text line3: 
ID: 12345 
Text line1: xxxx 
Text line2: x 
OS: "MacOS|Linux|Red Hat|Windows|Ubuntu|CentOS|Fedora" 
NotOS: "HP-UX" 
Text line3: 
ID: 12345 
+1

Спасибо! Это действительно работает! Как заставить OS/NotOS фактически показывать? – Metahuman

+0

Просто распечатайте их, например. change '{print $ 2}' to '{print m [" OS "], m [" NotOS "], $ 2}' Изменить ',' s на 'ORS' (разделитель выходной записи, по умолчанию - новая строка), если вы хотите, чтобы между ними были строки новой строки: '{print m [" OS "] ORS m [" NotOS "] ORS $ 2}'. Я настоятельно рекомендую вам прочитать книгу «Эффективное программирование Awk», 4-е издание, Арнольдом Роббинсом, если вы считаете, что теперь можете делать манипуляции с текстом сейчас или в будущем. –

Смежные вопросы