获取与第二个模式匹配的第一行的行号

时间:2019-06-14 12:52:14

标签: awk sed

是否可以使用awksed来获取某行的行号,使其成为与正则表达式匹配的第一行,然后是与另一个正则表达式匹配的另一行?

换句话说:

  1. 找到与正则表达式r1匹配的行l1。 l1是与r1匹配的第一行。
  2. 找到第l2行,下面。 l2匹配正则表达式r2。 l2是与r2匹配的第一行,而忽略了l1及以上的行。

说明:对于大多数通用解决方案,匹配是指部分匹配。 当然,部分匹配可以通过\<...\>变成全字匹配,或者通过^...$变成全行匹配。

示例输入:

- - '787928'
  - stuff
- - '810790'
  - more stuff
- - '787927'
  - yet more stuff
- - '828055'
  - some more stuff
- - '828472'
  - some other stuff

如果r1是^-.*787927.*并且r2是^-,我希望输出为7,即表示- - '828055'的行号。

3 个答案:

答案 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

如果第一次出现的pat1pat2在同一行,则上述操作将失败:

 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.*开始的行时,启动一个循环,用下一行替换当前行,直到一行开始-为止,并在此打印行号并退出。