是否可以使用awk
或sed
来获取某行的行号,使其成为与正则表达式匹配的第一行,然后是与另一个正则表达式匹配的另一行?
换句话说:
说明:对于大多数通用解决方案,匹配是指部分匹配。
当然,部分匹配可以通过\<...\>
变成全字匹配,或者通过^...$
变成全行匹配。
示例输入:
- - '787928'
- stuff
- - '810790'
- more stuff
- - '787927'
- yet more stuff
- - '828055'
- some more stuff
- - '828472'
- some other stuff
如果r1是^-.*787927.*
并且r2是^-
,我希望输出为7,即表示- - '828055'
的行号。
答案 0 :(得分:3)
输入示例:
world
zekfzlefkzl
fezekzevnkzjnz
hello
zeniznejkglz
world
eznkflznfkel
hello
zenilzligeegz
world
命令:
pat1="hello"; pat2="world";
awk -v pat1=$pat1 -v pat2=$pat2 '$0 ~ pat1{pat1_match = 1}($0 ~ pat2)&&pat1_match{print NR; exit}' <input>
输出:
6
答案 1 :(得分:3)
对于如下所示的输入文件:
1 pat2
2 x
3 pat1
4 x
5 pat2
6 x
7 pat1
8 x
9 pat2
您可以按以下方式使用sed:
$ sed -n '/pat1/,${/pat2/{=;q;};}' infile
5
其工作原理如下:
sed -n ' # suppress output with -n
/pat1/,$ { # for all lines from the first occurrence of "pat1" on...
/pat2/ { # if the line matches "pat2"
= # print line number
q # quit
}
}' infile
如果第一次出现的pat1
与pat2
在同一行,则上述操作将失败:
1 pat2
2 x
3 pat1 pat2
4 x
5 pat2
6 x
7 pat1
8 x
9 pat2
将打印3
。使用GNU sed,我们可以改用它:
$ sed -n '0,/pat1/!{/pat2/{=;q;};}' infile
5
sed -n ' # suppress output
0,/pat1/! { # for all lines after the first occurrence of "pat1"
/pat2/ { # if the line matches "pat2"
= # print line number
q # quit
}
}' infile
0
地址是GNU扩展名;如果1
位于第一行,则使用pat1
会中断。
答案 2 :(得分:0)
这可能对您有用(GNU sed):
sed -n '/^-.*787927.*/{:a;n;/^-/!ba;=;q}' file
遇到遇到以-.*787927.*
开始的行时,启动一个循环,用下一行替换当前行,直到一行开始-
为止,并在此打印行号并退出。