Reputation: 4795
Say I have this as input:
..pattern1...this
..pattern1...1
..pattern1...2
...
Or
..pattern1...0
..pattern2...0
..pattern1...1
..pattern2...1
..pattern2...2
..pattern1...this
...
I.e. list of lines containing only two types of patterns (strings).
I'm trying to obtain the first line of pattern1
after the last line of pattern2
. If there is no pattern2
then the first line of pattern1
.
Example output for both cases would be:
..pattern1...this
I can do either one of this cases separately with sed
(like with this answer) but I wasn't able to get a command which would do both ad the same time.
Anyone can jump in and lend an hand? Thanks!
Upvotes: 2
Views: 966
Reputation: 20980
awk '/pattern1/ && !line{line=$0} /pattern2/{line=""} END{print line}' file
pattern1
is found, set the line
variable to entire line.line
will already be set.)pattern2
is found, reset line
variable, so that the next occurance of pattern1
is respected.And Ed Morton's answer has already mentioned how to handle, if you want exact line match or if you want to take pattern from a shell variable. Adding my answer only to suggest that use of tac
can be avoided.
Upvotes: 1
Reputation: 203254
Given one interpretation of your question this might be what you need:
If pattern
means regexp
and you're OK with partial rather than full matches then:
tac file | awk '/pattern1/{line=$0; f=1} /pattern2/{exit} END{if (f) print line}'
If you need full regexp matches then add start/end anchors (/^pattern1$/
) and compare to a specific field (e.g. $4 ~ /^pattern1$/
) instead of the whole line if you need word instead of line matches.
If you need string matches instead of regexp then use index()
or ==
against $0
or $N
(where N is your target field number) as appropriate.
If pattern1 and pattern2 are shell variables and given a whole bunch of assumptions about what a "pattern" might be:
tac file | awk -v re1="$pattern1" -v re2="$pattern2" '$0 ~ re1{line=$0; f=1} $0 ~ re2{exit} END{if (f) print line}'
Upvotes: 1