4.11. How do I match only the first occurrence of a pattern?
(1) The general solution is to use GNU sed or ssed, with one of
these range expressions. The first script ("print only the first
match") works with any version of sed:
sed -n '/RE/{p;q;}' file # print only the first match
sed '0,/RE/{//d;}' file # delete only the first match
sed '0,/RE/s//to_that/' file # change only the first match
(2) If you cannot use GNU sed and if you know the pattern will
not occur on the first line, this will work:
sed '1,/RE/{//d;}' file # delete only the first match
sed '1,/RE/s//to_that/' file # change only the first match
(3) If you cannot use GNU sed and the pattern might occur on the
first line, use one of the following commands (credit for short GNU
script goes to Donald Bruce Stewart):
sed '/RE/{x;/Y/!{s/^/Y/;h;d;};x;}' file # delete (one way)
sed -e '/RE/{d;:a' -e '$!N;$ba' -e '}' file # delete (another way)
sed '/RE/{d;:a;N;$ba;}' file # same script, GNU sed
sed -e '/RE/{s//to_that/;:a' -e '$!N;$!ba' -e '}' file # change
Still another solution, using a flag in the hold space. This is
portable to all seds and works if the pattern is on the first line:
# sed script to change "foo" to "bar" only on the first occurrence
1{x;s/^/first/;x;}
1,/foo/{x;/first/s///;x;s/foo/bar/;}
#---end of script---