在行中搜索第一个项目,然后打印行和后续行

时间:2012-12-01 03:38:08

标签: unix awk grep

我正在尝试在文件中搜索名称,然后打印以下行。我原来是这样解决的:

grep -A 1 "searchterm" filename

然而,这会在行中的任何地方搜索searchterm;这是一个问题,因为我只想在该行的第一部分进行匹配。

例如,如果我在以下文件中查找1234

4567 otherstuff 1234
wrongsecondline
1234 otherstuff
rightsecondline

当我真正想要4567 otherstuff 1234wrongsecondline时,它会找到1234 otherstuffrightsecondline

有关如何仅搜索一行中的第一项,然后打印该行和第二行的任何想法?谢谢!

2 个答案:

答案 0 :(得分:2)

使用grep打印匹配行和以下行:

$ egrep -w -A1 "^1234" filename
1234 otherstuff
rightsecondline

使用awk实现与上述相同:

$ awk '$1=="1234"{print;getline;print}' filename
1234 otherstuff
rightsecondline

仅使用grep 打印匹配后的行(<之前注意filename):

$ grep -w -H --label=dummy -A1 '^1234' <filename | sed -ne 's#^dummy-##p'
rightsecondline

使用awk实现与上述相同:

$ awk '$1=="1234"{getline;print}' filename
rightsecondline

†如果没有两个连续的行包含搜索词,并且文件中的最后一行不包含搜索词


如果您希望连续两行或多行包含搜索词,例如

4567 otherstuff 1234
wrongsecondline
1234 otherstuff once
1234 otherstuff again
rightsecondline

...然后有条理地使用awk来获得与grep -A1相同的输出:

$ awk 'pr_after{print;pr_after=0}$1=="1234"{print;pr_after=1}' filename
1234 otherstuff once
1234 otherstuff again
rightsecondline

...并使用awk有状态地始终在匹配后打印该行,即使该行本身就是匹配:

$ awk 'pr_after{print;pr_after=0}$1=="1234"{pr_after=1}' filename
1234 otherstuff again
rightsecondline

...或有条不紊地使用awk仅在一条或多条匹配线后紧跟印刷非匹配线,实现与上述grep -H | sed相同的输出:

$ awk '$1=="1234"{pr_after=1;next}pr_after{print;pr_after=0}' filename
rightsecondline

在上面的示例中,$1=="1234"{...}pattern/action rule,如果第一列等于文本1234,则表示,然后执行... ,{{1 }}表示如果变量pr_after{...}设置为某个非零非空值,则执行... getline表示读取下一行并继续执行使用getline 之后的语句,而next表示读取下一行并以第一种模式重新开始评估

答案 1 :(得分:1)

使用grep对于此非常合理,假设您不想增强选择标准,但仅供参考,以下习语描述了如何使用awk选择给定特定模式匹配的记录范围:

a) Print all records from some pattern:

    awk '/pattern/{f=1}f' file

b) Print all records after some pattern:

    awk 'f;/pattern/{f=1}' file

c) Print the Nth record after some pattern:

    awk 'c&&!--c;/pattern/{c=N}' file

d) Print every record except the Nth record after some pattern:

    awk 'c&&!--c{next}/pattern/{c=N}1' file

e) Print the N records after some pattern:

    awk 'c&&c--;/pattern/{c=N}' file

f) Print every record except the N records after some pattern:

    awk 'c&&c--{next}/pattern/{c=N}1' file

g) Print the N records from some pattern:

    awk '/pattern/{c=N}c&&c--' file

我将变量名称从“f”变为“found”变为“c”变为“count”,因为它更能表达变量实际上是什么。

因此,对于这种情况,你可以使用上面的成语“c”:

awk 'c&&!--c;/1234/{c=1}' file