sof31
sof31

Reputation: 87

How to print everything between two patterns using awk

I can print everything between two patterns with this awk command:

awk '/'$1'/{a=1} a; /PATTERN2/{a=0}' ~/the/path/to/file.txt

What I need is to print everything between and include PATTERN1 and everything before PATTERN2 (which is always a line that starts with #.

Actually the patterns are hashtags like #france and #germany.

For example the file contains:

#france
France is a European country.
It's capital city is Paris.
One of its biggest cities is Lyon.

#germany
Germany is a European country.
It's capital city is Berlin.
One of its biggest cities is Munich.

What I want to be printed after calling #france:

#france
France is a European country.
It's capital city is Paris.
One of its biggest cities is Lyon.

Also it would be great if I can show the pattern in another color like blue or red.

Upvotes: 1

Views: 705

Answers (3)

RavinderSingh13
RavinderSingh13

Reputation: 133428

With your shown samples only, you can try following awk code. Where I am using RS(record separator) as paragraph mode and checking if line starts from particular string then print that whole para.

awk -v RS="" '$0~/^#france\n/' Input_file

Upvotes: 1

dawg
dawg

Reputation: 103744

You can use the pattern of setting a flag based on matching the section you want to print:

awk -v cc="#france" '/^#/{f=($1==cc)} f' file
#france
France is a European country.
It's capital city is Paris.
One of its biggest cities is Lyon.

Or:

awk -v cc="#germany" '/^#/{f=($1==cc)} f' file
#germany
Germany is a European country.
It's capital city is Berlin.
One of its biggest cities is Munich.

This will never start printing if there is not a match, and it only stops printing when another #hashtag is encountered.


How can I colorize the pattern?

You would use ANSI Escape Codes as in This Post. This is dependent if your terminal setup supports ANSI codes. Most do.

Example:

awk -v cc="#germany" '/^#/{
    f=($1==cc)
    if (f) printf("\033[0;31m%s\033[0m\n", $0)
    next 
    } 
    f' file

Prints (on my terminal):

#germany                             # red on black
Germany is a European country.       # green on black...
It's capital city is Berlin.         # green is the default color
One of its biggest cities is Munich.

Upvotes: 2

Daweo
Daweo

Reputation: 36360

If there is always blank line between entries you might harness paragraph mode of GNU AWK by setting RS to empty string, let file.txt content be

#france
France is a European country.
It's capital city is Paris.
One of its biggest cities is Lyon.

#germany
Germany is a European country.
It's capital city is Berlin.
One of its biggest cities is Munich.

then

awk 'BEGIN{RS=""}/^#france/' file.txt

output

#france
France is a European country.
It's capital city is Paris.
One of its biggest cities is Lyon.

Explanation: RS="" causes GNU AWK to treat paragraphs as rows. I simply filter rows which starts with (^) #france.

(tested in GNU Awk 5.0.1)

Upvotes: 2

Related Questions