Reputation: 1
I am not really sure if this is already out there but I am having some trouble trying to express what I want to be done in a search field.
Say I had a file like the following
foo1
foo2
foo3
barbarbar
barbarbar
barbarbar
foo4
foo5
barbarbar
barbarbar
barbarbar
foo6
foo7
I want to only get the fields that have something other than "foo#" after a "foo#". I also want the "foo#" to be printed if it does have barbarbar after it and everthing that until the next "foo#". An example output would be below.
foo3
barbarbar
barbarbar
barbarbar
foo5
barbarbar
barbarbar
barbarbar
Upvotes: 0
Views: 44
Reputation: 246774
I don't normally like to post answers to questions that "haven't tried", but I've got some time on my hands. I like to use awk for stuff like this:
The "state machine" approach:
awk '
/foo/ && afterfoo != "" { print currentfoo; print afterfoo; afterfoo = "" }
/foo/ { currentfoo = $0 }
!/foo/ { afterfoo = afterfoo $0 "\n" }
END { if (afterfoo != "") {print currentfoo; print afterfoo} }
' file
The "reverse-process-reverse" approach:
tac file | awk '
!/foo/ { print; seenfoo = 0 }
/foo/ && !seenfoo++
' | tac
Upvotes: 1
Reputation: 24802
It looks like this sed
command will work :
sed -n '/^foo[0-9]$/{N;:l;/\nfoo[0-9]$/{D;bl};p;b};p'
I honestly regret trying to do that with sed
though, the result is hardly comprehensible.
/^foo[0-9]$/{ # if a line matches fooX
N # retrieve another line
:l # we'll jump to here later ; label l
/\nfoo[0-9]$/{ # if the following line matches fooX too
D # discard the first line and consume another one
bl # jump back to l
} # at this point we have a fooX line followed by a non-fooX line
p # print what we've matched
b # stop processing this line (jump to the end of the script)
} # reached when the first line read doesn't match fooX
p # print the line
Edit : now that I've laid it out this way, I notice that the p;b
part can be removed since it will behave the same by reaching the last p
. If I was the poor soul having to maintain this, I think I'd rather have it there though.
Upvotes: 2