Sample Header Ad - 728x90

How to extract a sub-heading as string which is above a search for word

1 vote
2 answers
93 views
I'm new to Bash and I've been self-taught. I think I'm learning well, but I do have staggering gaps in my base knowledge. So sorry if this is woefully simple bbuuuttt... Essentially, I need to sift through a large amount of data and pull out specific phrases. I've been making slow and steady progress, but I'm now stuck on getting a heading for a line of data. Here's what the file looks like:
A lot (AND I MEAN A LOT) of data above  
STATE  1:
133a -> 135a  :     0.010884 (c= -0.10432445)
134a -> 135a  :     0.933650 (c= -0.96625573)

STATE  2:
129a -> 135a  :     0.016601 (c= -0.12884659)
130a -> 135a  :     0.896059 (c= -0.94660402)
130a -> 136a  :     0.011423 (c=  0.10687638)
130a -> 137a  :     0.023884 (c= -0.15454429)
130a -> 138a  :     0.020361 (c= -0.14269354)

STATE  3:
133a -> 135a  :     0.899436 (c= -0.94838591)
134a -> 136a  :     0.012334 (c= -0.11106052)       

STATE  4:
129a -> 135a  :     0.688049 (c= -0.82948703)
129a -> 136a  :     0.212819 (c= -0.46132295)
129a -> 137a  :     0.036987 (c=  0.19231930)
130a -> 135a  :     0.011990 (c=  0.10949722)
134a -> 135a  :     0.922010 (c= -0.98192034)
There are many more states (up to 30) of varying length below, which may also include what I'm looking for. And then more data below that I have got the numbers I am looking for saved in variables. (134 and 135 for this example) And I can use :
"${a}a -> ${b}a" File.Name;
to show me the lines that have 134 -> 135 on, but I need the STATE that they are in. I've tried using grep to look above the found lines to the nearest line with STATE in, but I couldn't figure out how to set the length of -B as a condition rather than a number (don't know if it can be done). I have also tried with awk and sed to find the line with STATE and look below to see if 134 -> 135 is benethe it before the next STATE, but I couldn't find a way to stop it and not print at the next STATE instead of just continuing until it found the next 134 -> 135. The Ideal output (for the above example) would be:
STATE  1
STATE  4
but
STATE  1:
133a -> 135a  :     0.010884 (c= -0.10432445)
134a -> 135a  :     0.933650 (c= -0.96625573)
STATE  4:
129a -> 135a  :     0.688049 (c= -0.82948703)
129a -> 136a  :     0.212819 (c= -0.46132295)
129a -> 137a  :     0.036987 (c=  0.19231930)
130a -> 135a  :     0.011990 (c=  0.10949722)
134a -> 135a  :     0.922010 (c= -0.98192034)
is also absolutely fine. I just need it to spit out the correct STATES and no others. It doesn't really matter what other data comes with it. Also, this is going to be applied to about 40 other files with similar layouts, so I need it not to be specific to this one (aka not grep STATE 1 and grep state 4) I'm hoping someone can help me or tell me if this is impossible to do.
Asked by TC575 (13 rep)
Jul 11, 2025, 08:37 PM
Last activity: Jul 16, 2025, 09:53 AM