sed behaving oddly, repeats lines

Hi, all.

Here's the problem:

sed '/FOO/,/BAR/p'

That should print anything between FOO and BAR, right?

Well, let's say I have file.txt that contains just one line "how are you today?".
Then I run something like the above and get:

$ sed '/how/,/today/p' file.txt
how are you today?
how are you today?

It prints the line twice when I was expecting it to print just "are you".
I tried several text files with different content and also played around a little bit with quoting and regexps and in every case I got the line or the entire text duplicated.

I'm pretty sure the problem is mine and not sed's but I can't figure out what I'm doing wrong.

Any ideas?
- - - - - - - - -

Off Topic
Thanks to all of you out there. Reading this forum got me out of trouble many times :wink:

From man pages for sed:

       -n     Suppress	the  default  output  (in which each line, after it is
	      examined for editing, is written to standard output). Only lines
	      explicitly selected for output are written.

This should also help.

1 Like

Explain this :frowning:

 echo "how are you today?" | sed '/how/,/today/p' 

This gives me as below

 
how are you today?
how are you today?

Why is this?

Because sed prints every line by default anyway, unless you use -n or unless you delete the line. The p command in that sed script also prints it. So, that script will print lines that match twice and lines that don't match once.

You can either use -n option or you can invert the logic:

sed '/how/,/today/!d'

Note the ! . That deletes every line that does not match.

Regards,
Alister

Oh, I see! Thank you very much!!

I misunderstood how sed and '/FOO/,/BAR/p' work.

In a multiple line file, I get all the lines between the patterns, as expected, using the -n flag, without any extra output. .

When providing a one line file (or a line of text using | ), it prints out the whole line, which makes sense after reading what you explained in the other post.

I'm working on a file with several lines, so the -n does the trick. But I'm still curious on how to print a string between two patterns of a single line using sed.

I get that clearly.

So what if I want to just get the characters between how and today??

Isn't this sed-1-liner supposed to do that?

Alister, thanks! That's really helpful. I need to get my hands on a thorough sed manual

Expecting something like this?

$ echo "how are you today?" | sed 's/.*how\(.*\)today.*/\1/'
 are you 

---------- Post updated at 01:55 PM ---------- Previous update was at 01:47 PM ----------

You need to learn the line addressing mechanism of sed.

sed -n '/how/,/today/p' inputfile

The 2 addresses refer to 2 different lines and not the same line. This will print out all sections of the file which start with a line containing 'how' and end with one containing 'today', both lines inclusive.

2 Likes

Great!
I'm guessing the comma in the other case is representative of the whole line itself.
Got my hands on some documentation, so I'm off to RTFM :stuck_out_tongue:

Thanks!!

@elixir_sinari: Thanks for the one liner. :slight_smile:

Btw, looking at the line,

 sed 's/.*start\(.*\)end.*/\1/' file 

it would work fine when a line contains only one combination of start-end.

Consider this, what if the input is like below,

It start here and end here.
It start and end & start and end & start and end recursively.

Thanks in advance :slight_smile: