Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how can I get sed to quit after the first matching address range?

Tags:

regex

sed

I have a file:

header trigger text1 text2 trigger text5 trigger ... trigger ... 

I want sed to only match between the first two occurrences of 'trigger'. So I tried:

sed -n '/trigger/,/trigger/p' 

But as the man page for sed says, that matches all occurrences within two lines with 'trigger'. I want sed to quit after the first match, so the output would be:

trigger text1 text2 trigger 

How do I accomplish this?

like image 721
PonyEars Avatar asked Jan 06 '14 04:01

PonyEars


People also ask

How do I quit SED?

(quit) Exit sed without processing any more commands or input. (quit) This command is the same as q , but will not print the contents of pattern space. Like q , it provides the ability to return an exit code to the caller.

Which is the correct command to replace the first occurrence?

By default, the sed command replaces the first occurrence of the pattern in each line and it won't replace the second, third… occurrence in the line.

What does R mean in SED?

r is used to read a file and append it at the current point. The point in your example is the address /EOF/ which means this script will find the line containing EOF and then append the file specified by $thingToAdd after that point. Then it will process the rest of the file.


2 Answers

You can do this with a loop in GNU sed:

sed -n '/trigger/{p; :loop n; p; /trigger/q; b loop}' 

Explanation:

  1. When you see the first /trigger/, start a block of commands
  2. p -- print the line
  3. :loop -- set a label named loop
  4. n -- get the next line
  5. p -- print the line
  6. /trigger/q -- if the line matches /trigger/ then exit sed
  7. b -- jump to loop
like image 85
janos Avatar answered Oct 05 '22 20:10

janos


While jason's ans is what you're looking for, I would have preferred using awk for this task

awk '/trigger/{p++} p==2{print; exit} p>=1' file 

Output:

trigger text1 text2 trigger 

This would provide more flexibility to chose lines between nth and mthe occurrence of trigger.

E.g.

$ awk -v n=2 -v m=3 '/trigger/{p++} p==m{print; exit} p>=n' file trigger text5 trigger 
like image 33
jkshah Avatar answered Oct 05 '22 19:10

jkshah