如何获得匹配字符串之后的第一行,而不管字符串是否存在

时间:2019-06-04 14:21:24

标签: bash

说我有这个输入:

..pattern1...this
..pattern1...1
..pattern1...2
...

..pattern1...0
..pattern2...0
..pattern1...1
..pattern2...1
..pattern2...2
..pattern1...this
...

即仅包含两种类型的模式(字符串)的行列表。 我正在尝试在pattern1 last 行之后获得pattern2 first 行。如果没有pattern2,则pattern1的第一行。 两种情况的示例输出为:

 ..pattern1...this

我可以分别使用sedlike with this answer)来执行上述任一情况,但是我无法获得同时执行这两个广告的命令。

任何人都可以伸手伸出援手吗?谢谢!

2 个答案:

答案 0 :(得分:1)

针对您的问题的一种解释,这可能就是您所需要的:

如果pattern的意思是regexp,那么您可以部分匹配而不是全部匹配,那么您可以:

tac file | awk '/pattern1/{line=$0; f=1} /pattern2/{exit} END{if (f) print line}'

如果需要完整的正则表达式匹配,则添加开始/结束锚点(/^pattern1$/)并与特定字段(例如$4 ~ /^pattern1$/)进行比较,而不是整行(如果需要单词而不是行匹配)。

如果您需要字符串匹配而不是正则表达式,请根据需要对index()==(其中N是您的目标字段编号)使用$0$N

如果pattern1和pattern2是shell变量,并且给出了关于“模式”可能是什么的大量假设:

tac file | awk -v re1="$pattern1" -v re2="$pattern2" '$0 ~ re1{line=$0; f=1} $0 ~ re2{exit} END{if (f) print line}'

答案 1 :(得分:1)

awk '/pattern1/ && !line{line=$0} /pattern2/{line=""} END{print line}' file
  1. 找到pattern1后,将line变量设置为整行。
  2. 再次找到pattern1时,将其忽略。 (因为line已经设置。)
  3. 找到pattern2时,请重置line变量,以确保下次出现pattern1

埃德·莫顿(Ed Morton)的答案已经提到了如何处理,如果您想精确匹配行还是要从shell变量中提取模式。添加我的答案只是为了建议可以避免使用tac