I have the following text:


I would like to extract firstgroup using sed.

I tried sed -nr 's/.*START(.*)END.*/\1/p', but it doesn't work, it extracts all matches not only the first one.

  • 2
    Append | head -n 1 or with GNU grep: grep -Po -m 1 '(?<=START).*(?=END)' – Cyrus Jul 19 '20 at 0:05
sed -nr '/.*START(.*)END.*/{s/.*START(.*)END.*/\1/p;q}'
# or (probably faster)
sed -nr 's/.*START(.*)END.*/\1/p; t quit; b end; : quit; q; : end;'
  • 2
    ... or with GNU sed's T (branch on non-match), sed -nr 's/.*START(.*)END.*/\1/p;T;q' – steeldriver Jul 19 '20 at 0:10
  • 2
    There's no need to repeat the regex: sed -nr '/.*START(.*)END.*/{s//\1/p;q;}' – Rakesh Sharma Jul 19 '20 at 4:01

With GNU , assuming there's at most one START...END per line:

grep -oPm1 'START\K.*?(?=END)' file

With , assuming the first occurrence is on the first line and that there's no END before the first START and that there's no START in the value to be returned:

awk -F'START|END' '{print $2;exit}' file


awk -F'START|END' '$0 ~ FS {print $2;exit}' file

With :

perl -lne 'do{ print $1; last } if /START(.*?)END/' file


  • Both awk|perl will exit prematurely incase a noninteresting line appears first. – Rakesh Sharma Jul 19 '20 at 3:58
  • 1
    perl -lne 'print($1),last if /START(.*?)END/' – Rakesh Sharma Jul 19 '20 at 4:03
  • 1
    awk -F'START|END' '$0 ~ FS{print $2;exit}' Assuming the START/END come in pairs only. – Rakesh Sharma Jul 19 '20 at 4:06
  • grep -oPm1 'START\K.*?(?=END)' to scrimp on backtracking in the best case or catch an unintended END in the worst case. – Rakesh Sharma Jul 19 '20 at 4:11
  • PS: Hope you don't mind my comments. Coz I've observed folks get testy when given some comments. – Rakesh Sharma Jul 19 '20 at 4:14

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.