如果AWK中满足条件,则打印行范围

时间:2019-03-23 14:19:50

标签: linux awk

我要执行的操作是使用awk在满足一定条件的行上方显示2行,在行下方显示2行。例如,我正在搜索字符串'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 个答案:

答案 0 :(得分:2)

$ 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--;代表一个真实的条件,由于满足条件的同时也设置了n,因此会导致awk打印(默认操作)当前行加上c=n+1的后续行。将打印当前行并递减c直到c达到零。

答案 1 :(得分:2)

请尝试以下操作,简单的grep就可以完成此任务。

grep -A2 -B2 '^s62234:' Input_file

更准确地说,您可以尝试按照以下步骤将确切的字符串与grep匹配:

grep -C2  '^s62234:' Input_file

答案 2 :(得分:1)

使用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

您可以通过将前行存储在数组中并使用循环来动态处理前行的数量。