0

I have some data like this

Data                    Table ABC
Data
Stop
Data
Data                    Stop
Data                    Foo
Data                    Foo

I am trying to setup an awk range for Table ABC until Stop in the same column. I have tried this so far

awk '/Table ABC/,/Stop/' q
Data                    Table ABC
Data
Stop

But I desire to get

Data                    Table ABC
Data
Stop
Data
Data                    Stop
NinjaGaiden
  • 3,046
  • 6
  • 28
  • 49
  • range patterns are very convenient but not extensible and you may paint yourself to a corner when extra features are needed. – karakfa May 17 '17 at 21:03
  • No forgiveness necessary but have you tried solving your problem without a range expression? That **IS** the right approach so if you try it as you've been shown I think you may not actually have a question to ask. – Ed Morton May 17 '17 at 21:22

2 Answers2

2

if the data file is not tabulated but in fixed length formatted, perhaps an alternative solution will work better

awk '{m=match($0,"Table ABC"); if(m>0) p=m} 
   p {print; if(p==match($0,"Stop")) exit}' file

Data                    Table ABC
Data
Stop
Data
Data                    Stop

mark the position of the match, start printing and end when the position matches the end pattern.

Regardless of the location of the match, if you want to end at the second occurrence of the end pattern:

awk '/Table ABC/{p=1} p; /Stop/ && ++c==2{exit}' file

counter c counts the end patterns and exits at the second time.

karakfa
  • 66,216
  • 7
  • 41
  • 56
  • Yeah. I am doing something similar. awk '/Table ABC/{f=1} f{print} / Stop/{f=0}' I put a space in / Stop/. – NinjaGaiden May 17 '17 at 21:03
  • that's the equivalent of the range pattern, just need to add counter. Note also if you have only one instance to match (or the first) you can replace `f=0` with `exit`. – karakfa May 17 '17 at 21:05
1

awk range pattern solution:

awk -F"[[:space:]][[:space:]]+" '$2=="Table ABC", $2=="Stop"' file

The output:

Data                    Table ABC
Data
Stop
Data
Data                    Stop

A range pattern is made of two patterns separated by a comma, in the form ‘begpat, endpat’. It is used to match ranges of consecutive input records. The first pattern, begpat, controls where the range begins, while endpat controls where the pattern ends.

RomanPerekhrest
  • 88,541
  • 4
  • 65
  • 105
  • if its a pattern, is it possible to do a negate? Such as, don't do first match? I am not good with regex thats why i ask. (?^Stop)? – NinjaGaiden May 17 '17 at 20:41
  • @NinjaGaiden, **When a record matches begpat, the range pattern is turned on, and the range pattern matches this record as well. As long as the range pattern stays turned on, it automatically matches every input record read. The range pattern also matches endpat against every input record; when this succeeds, the range pattern is turned off again for the following record.** – RomanPerekhrest May 17 '17 at 20:49
  • @NinjaGaiden, yes, we can use "negation" pattern but it'll impact the whole range – RomanPerekhrest May 17 '17 at 20:51
  • Never use the word `pattern` in this context as it's ambiguous. Use the word `string`, or `regexp`, or `condition` or `expression` - whichever it is you mean. In the above conversation `pattern` is being used to mean multiple different things which just muddies the waters. I know some awk documentation talks about patterns - that is a confusion-generator! – Ed Morton May 17 '17 at 21:18