4

I have one requirement. Let’s say my file contents are

a
b
c
d
e
f
d
e
f

I want to print the lines from b to 2nd time repeated d. Is there any command using awk to do this?

Output should be

b
c
d
e
f
d

If it is first time b, I know the command

awk '/b/,/d/' file.txt

But I want to print the text to the matching point if it repeats second time. I want to have the command with in one line.

7

One way is to use flags and counter to keep track

$ awk '/b/{f=1; c=0} f; /d/ && ++c==2{f=0}' file.txt
b
c
d
e
f
d
  • /b/{f=1; c=0} set flag for starting match and initialize counter
  • f; print input record as long flag is set
  • /d/ && ++c==2{f=0} clear the flag if ending string is matched for second time
  • can simplify to awk '/b/{f=1} f; /d/ && ++c==2{exit}' if there is only one set to be extracted


Note that if ending match doesn't have 2 matches, it will print until end of input

$ seq 10 | awk '/4/{f=1; c=0} f; /6/ && ++c==2{f=0}'
4
5
6
7
8
9
10
  • 1
    You could also let f double as the counter, e.g.: /b/ { f=2 } f; /d/ { f-- } – Thor Nov 13 '17 at 9:04
  • @Thor good idea, but need /d/ && f{ f-- } as negative numbers evaluate as true – Sundeep Nov 13 '17 at 9:14
1
  1. A more readable code. Keep track of the counts of characters.
  2. Print as long as count of b=1 and d<=2.
  3. Stop once count of d has reached 2.

    awk '{ a[$1]++;
        if(a["b"]==1 && a["d"]<=2){
            print;
        }
        if(a["d"]==2){
           a["d"]=10
        }
    }' file.txt
    

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.