2

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

grep -A 1 "searchterm" filename

但是,这会搜索searchterm行中的所有位置;这是一个问题,因为我只希望在该行的第一部分匹配。

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

4567 otherstuff 1234
wrongsecondline
1234 otherstuff
rightsecondline

它会找到4567 otherstuff 1234and wrongsecondline,当我真的想要1234 otherstuffand时rightsecondline

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

4

2 回答 2

2

用于grep打印匹配的行和以下行:

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

用于awk实现与上述相同的†</sup>:

$ 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实现与上述相同的†</sup>:

$ 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"{...}是一个模式/动作规则,表示如果第一列等于文本,1234则执行...pr_after{...}表示如果变量pr_after设置为某个非零非空值,则执行...getline表示读取下一个line 并继续执行 getline 之后的语句,而next意味着读取下一行并在第一个模式处重新开始评估

于 2012-12-01T03:56:25.703 回答
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

我将变量名称从“found”的“f”更改为“count”的“c”,因为这更能表达变量的实际含义。

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

awk 'c&&!--c;/1234/{c=1}' file
于 2012-12-02T05:32:19.370 回答