1

I am having difficulty grabbing a few lines from text file. For instance say I have the following text in a file:

A I have a cat
B I have a dog
C I have a mouse
X I have a monkey
B I have a rat
T I have a cat
C I have a deer
X I have a turkey

I am trying to find all lines that contain the word "cat" and if the sentence has an "A" as the first letter, I'd like to get the next few lines (including the line that matched the pattern "cat") until I encounter the letter "X" as the first letter of a line.

So for instance, the above text file should print out:

A I have a cat
B I have a dog
C I have a mouse

(prints out until it sees the X)

Note: The line "T I have a cat" should not match because even though it has cat it does not start with the letter "A"

I tried searching for help but could not find anything on printing out lines until a certain pattern is matched. The closest I could find was

awk '/cat/ {for(i=0; i<=5; i++) {getline; print}}' filename

but that prints out a certain number of lines. I want it to print out until it sees the next pattern which is an "X"

Ed Morton
  • 188,023
  • 17
  • 78
  • 185
yunli.tang
  • 115
  • 1
  • 6
  • If you're ever considering using getline then please read http://awk.info/?tip/getline so you understand why that's almost always the wrong approach and how to implement it robustly in those rare occasions when it is the right approach. – Ed Morton Apr 21 '16 at 16:40
  • 1
    Thanks for the tip @EdMorton – yunli.tang Apr 21 '16 at 16:46

2 Answers2

3

Using sed instead of awk:

$ sed -n '/^A.* cat/,/^X/{/^X/d;p;}' data
A I have a cat
B I have a dog
C I have a mouse
$
  • -n — do not print by default,
  • /^A.* cat/ — from a line starting with A and containing cat after a space (adjust to suit definitions of cat; it would pick up A I visited the catacombs, for example),
  • /^X/ — up to a line starting with X,
  • {/^X/d; — delete any line (the only line) starting with X, and move on to process the next line,
  • p;} — print the line.

As shown, it will work with BSD sed and GNU sed; GNU sed does not require the final semicolon.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • Here is another `sed` way to selective print: `sed -n '/^A.*cat/,/^X/{/^X/!p}' file` –  Apr 21 '16 at 18:11
1
$ awk '/^X/{f=0} /^A.*cat/{f=1} f' file
A I have a cat
B I have a dog
C I have a mouse
Ed Morton
  • 188,023
  • 17
  • 78
  • 185