如何编写一个awk
脚本来扫描输入文件中的“start”并找到包含“next”的行并显示以下行?像这样的东西:
[user]$ cat test.txt
start
next
This line should print
Ignore this
[user]$ display.awk test.txt
This line should print
[user]$ cat test1.txt
Ignore this
next
Ignore this
start
Ignore this
next
This line should print
Ignore this
next
Too late so ignore this too
start
Ignore this too
[user]$ display.awk test1.txt
This line should print
答案1
这是一句:
awk 'BEGIN {start="no"; nextline="no"}; nextline=="yes" {print; exit}; (start=="yes" && /^next$/) {nextline="yes"}; /^start$/ {start="yes"}' test.txt
作为独立脚本:
#!/bin/awk -f
BEGIN {start="no"; nextline="no"}
nextline=="yes" {print; exit}
(start=="yes" && /^next$/) {nextline="yes"}
/^start$/ {start="yes"}
解释
首先阅读第一个点,然后反向阅读其余的点可能更有意义。
BEGIN {start="no"; nextline="no"}
:首先,将两个变量设置为"no"
(即我们还没有找到它们)。 NBnext
是保留字,所以我用了nextline
。nextline=="yes" {print; exit}
next
:当我们从上一行找到后,打印该行然后退出。(start=="yes" && /^next$/) {nextline="yes"}
:找到 后start
,如果我们next
在一行中也找到,则设置nextline
为"yes"
/^start$/ {start="yes"}
:如果我们找到开始,则设置start
为"yes"
。
答案2
替代解决方案sed
:
sed -n '/start/,${ # in this range
$!{ # if not the last line
/next/{ # and if line matches "next"
n # read in the next line
p # print pattern space
q # quit
}
}
}' infile
和gnu sed
:
sed -n '/start/,${$!{/next/{n;p;q}}}' infile
答案3
这也应该有效
awk 'BEGIN {l1=0} /^start$/{l1=1} /^next$/ && l1==1 {l2=NR+1} NR==l2 {print;l1=0}' test.txt
它使用记录号 NR 来打印起始行后遇到的第一个下一个之后的记录。