Bhaskar
Bhaskar

Reputation: 357

filter out a substring from a string in linux only once

I am trying to extract a particular substring from a string that I have using sed command in linux. However, the issue is that after the command has returned me the substring the first time, I again looks for the starting keyword in the string.

I want to skip the last part. I just want the first substring between the keywords.

String: bhaskar.txt

bhaskar
rahul
gaurav
ganesh
bhaskar
rahul

Substring required: Everything between "bhaskar" and "ganesh"

Command used: sed -n '/bhaskar/,/ganesh/p' bhaskar.txt

output:

bhaskar
rahul
gaurav
ganesh
bhaskar
rahul

Expected Output:

bhaskar
rahul
gaurav
ganesh

Upvotes: 3

Views: 699

Answers (3)

glenn jackman
glenn jackman

Reputation: 246774

With sed, you need to use a loop:

sed -n '/bhaskar/{: loop; p; /ganesh/q; n; b loop}' bhaskar.txt

Upon second thought, not so, you just need to quit at the end of the range:

sed -n '/bhaskar/,/ganesh/p; /ganesh/q'

Upvotes: 0

konsolebox
konsolebox

Reputation: 75478

Using awk:

awk -v a=bhaskar -v b=ganesh '$0 == a { p = 1; t = "" }; $0 == b && p { printf "%s%s\n", t, b; p = 0 }; p { t = t $0 ORS }' file

Output:

bhaskar
rahul
gaurav
ganesh

Upvotes: 0

Tom Fenech
Tom Fenech

Reputation: 74595

Here's how you could do it in awk:

awk '/bhaskar/ && !p++, /ganesh/' bhaskar.txt

The first time /bhaskar/ matches, p is not yet defined, so !p is true and the range begins. The p++ means that after the value has been checked, increment p by 1. The range will continue until /ganesh/ matches.

After the first range has completed, if /bhaskar/ matches again, p will be positive, so !p will evaluate to false and the range will not restart.

Output:

bhaskar
rahul
gaurav
ganesh

Here's another way you could do it, that some may prefer:

awk '/bhaskar/ {p=1} p {print} /ganesh/ {exit}' bhaskar.txt

Arguably more self-explanatory, it sets a variable p as soon as /bhaskar/ matches, prints when the variable p is set and exits (after printing) when /ganesh/ matches.

Upvotes: 3

Related Questions