Reputation: 1375
I am trying to find the preceding string before another string. For example:
StringA <stuff 1>
StringA <stuff 2>
StringD
...
StringB <stuff 3>
StringA <stuff 4>
StringA <stuff 5>
StringA <stuff 6>
StringD
StringB <stuff 7>
I want to find all the "StringA" that JUST preceeds StringB in the file.
The output in this example would be:
StringA <stuff 2>
StringA <stuff 6>
I am able to do find the line numbers of all the StringB by using: grep -n "StringB"
Then I can use sed -n 1,$line_numberp which makes me go from line 1 to the line of StringB. I do grep "StringA" | tail -n1
This seems to be work but is a bit cumbersome. Is there any better way to achieve the desired result please?
Upvotes: 1
Views: 1534
Reputation: 58473
This might work for you (GNU sed):
sed ':a;$!N;/^StringA/!D;/^\(StringA\).*\n\1/D;/.*StringB/!ba;P;D' file
This removes duplicate StringA
lines retaining the last and when encountering a StringB
line prints out the first string in the pattern space.
Upvotes: 0
Reputation: 1725
With awk :
awk '/^StringB/ { if(lastline ~ /^StringA/) {print lastline }} {lastline=$0}' $file
StringA and StringB can be regular expressions.
Upvotes: 1
Reputation: 11090
grep "\(StringA\|StringB\)" $file_name | grep -B 1 StringB | grep StringA
Upvotes: 3
Reputation: 98068
sed '/String[AB]/!d' input |
sed -n -e '/StringA/{:l /StringA/h;n;/StringB/{x;p;b};bl}'
With comments:
sed '/String[AB]/!d' input | # remove lines not containing StringA/B
sed -n -e '/StringA/{ # if line contains StringA, then
:l # loop until StringB
/StringA/h; # keep the most recent A in the hold space
n; # read a newline (overwrite pattern space)
/StringB/!bl; # loop up...
x;p;b # get the most recent A, and print
}'
Upvotes: 1