Вывести диапазон строк, если условие выполнено в AWK - PullRequest
2 голосов
/ 23 марта 2019

То, что я пытаюсь сделать, это показать 2 строки выше и 2 строки ниже линии, которая соответствует определенным критериям без канала, используя awk. Например, я ищу строку 's62234' и, когда она найдена, я хочу напечатать все строки, ограниченные синим прямоугольником, как показано на прикрепленном снимке экрана.

Это файл, который я использую (thefmifile.txt)

s62098:x:1271:504:Velizar Vrabchev,SI,3,1:/home/SI/s62098:/bin/bash
s62101:x:1272:504:Georgi Georgiev,SI,3,5:/home/SI/s62101:/bin/bash
s62108:x:1273:504:Sherif Kunch,SI,3,1:/home/SI/s62108:/bin/bash
s62111:x:1274:504:Yulian Bizeranov,SI,3,3:/home/SI/s62111:/bin/bash
s62121:x:1275:504:Daniel Dimitrov,SI,2,1:/home/SI/s62121:/bin/bash
s62133:x:1276:504:Ivaylo Ivanov,SI,2,2:/home/SI/s62133:/bin/bash
s62160:x:1277:504:Veniyana Tsolova,SI,2,3:/home/SI/s62160:/bin/bash
s62199:x:1278:504:Nikola Petrov,SI,2,5:/home/SI/s62199:/bin/bash
s62219:x:1279:504:Viliyan Ivanov,SI,2,6:/home/SI/s62219:/bin/bash
s62234:x:1280:504:Viktoriya Dobreva,SI,2,3:/home/SI/s62234:/bin/bash
s855264:x:1281:504:Toni Dupkarski,SI,4,2:/home/SI/s855264:/bin/bash
s81555:x:1282:503:Elena Georgieva,KN,2,0:/home/KN/s81555:/bin/bash
s81585:x:1283:503:Stela Marinova,KN,2,0:/home/KN/s81585:/bin/bash
s81441:x:1284:503:Vesela Plamenova Borislavova , KN, k2, g7:/home/KN/s81441:/bin/bash
s81644:x:1285:503:Viktor Rusev, KN, k2, g7:/home/KN/s81644:/bin/bash
s81628:x:1286:503:Iliyan Yordanov Yordanov, KN, k2, g6:/home/KN/s81628:/bin/bash
s81490:x:1287:503:Yana Spasova, KN, k2, g6:/home/KN/s81490:/bin/bash

enter image description here

Я попытался с помощью awk найти строку, которая соответствует критериям, и использовать NR, чтобы получить номера других необходимых строк, но, похоже, я что-то упустил.

Вот команда, которую я использовал:

cat thefmifile.txt | awk -F ':' '$1==s62234 {for (x = NR -2; x <= NR + 2; x++){print}}'

Вывод на скриншоте ниже.

enter image description here

И это желаемый вывод:

s62199:x:1278:504:Nikola Petrov,SI,2,5:/home/SI/s62199:/bin/bash
s62219:x:1279:504:Viliyan Ivanov,SI,2,6:/home/SI/s62219:/bin/bash
s62234:x:1280:504:Viktoriya Dobreva,SI,2,3:/home/SI/s62234:/bin/bash
s855264:x:1281:504:Toni Dupkarski,SI,4,2:/home/SI/s855264:/bin/bash
s81555:x:1282:503:Elena Georgieva,KN,2,0:/home/KN/s81555:/bin/bash

Когда это {print x}, он показывает номера нужных мне строк, но есть ли какой-нибудь способ получить доступ к строкам файла как элементам массива и просто использовать этот 'x' в качестве индекса (например, что-то как NR [x])?

Или есть какой-то другой способ получить эти строки? Спасибо!

Ответы [ 3 ]

2 голосов
/ 23 марта 2019
$ awk -v n=2 -F':' '$1=="s62234"{for (i=0;i<n;i++) print buf[(NR+i)%n]; c=n+1} c&&c--; {buf[NR%n]=$0}' file
s62199:x:1278:504:Nikola Petrov,SI,2,5:/home/SI/s62199:/bin/bash
s62219:x:1279:504:Viliyan Ivanov,SI,2,6:/home/SI/s62219:/bin/bash
s62234:x:1280:504:Viktoriya Dobreva,SI,2,3:/home/SI/s62234:/bin/bash
s855264:x:1281:504:Toni Dupkarski,SI,4,2:/home/SI/s855264:/bin/bash
s81555:x:1282:503:Elena Georgieva,KN,2,0:/home/KN/s81555:/bin/bash

buf[] - это просто массив, в котором хранятся строки n, предшествующие текущей строке, поэтому они могут быть напечатаны при выполнении условия $1=="s62234".c&&c--; представляет истинное условие, которое заставит awk напечатать (действие по умолчанию) текущую строку плюс n последующие строки из-за того, что c=n+1 также устанавливается при выполнении вашего условия - то есть он напечатает текущую строку иуменьшение c до тех пор, пока c не достигнет нуля.

2 голосов
/ 23 марта 2019

Не могли бы вы попробовать следующее, простой grep может справиться с этой задачей.

grep -A2 -B2 '^s62234:' Input_file

Также более точно вы можете попробовать следовать, чтобы соответствовать точной строке с grep:

grep -C2  '^s62234:' Input_file
1 голос
/ 23 марта 2019

Это легко сделать с помощью grep:

-B, --before-context=NUM  print NUM lines of leading context
-A, --after-context=NUM   print NUM lines of trailing context
-C, --context=NUM         print NUM lines of output context
-NUM                      same as --context=NUM

С помощью awk вы можете сделать что-то вроде этого:

awk -F ':' '$1==s62234{print l2;print l1;a=3}a&&a-->0{print}{l2=l1;l1=$0}' thefmifile.txt

Вы можете динамически обрабатывать количество предшествующих строк, сохраняя ихв массиве и используя цикл.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...