Você não especificou exatamente quais são seus requisitos. Você pode querer um processo de várias etapas. Escolha uma string que você sabe que não ocorrerá na sua entrada (por exemplo, #### ):
echo "The quick brown fox jumps over 42 lazy dogs in 2012 and 2013." \
| sed \
-e "s/[0-9]\{4\}/###/" \
-e "s/fox.*####//" \
-e "s/####//"
(Comando excessivamente dobrado para facilitar a leitura). O -e "s/[0-9]\{4\}/&####/" injeta #### depois do primeiro número de quatro dígitos. (Aviso: isso alterará 65536 para 6553####6 .)
-e "s/fox.*####//" afeta linhas que contêm fox e #### - ou seja, linhas que contêm pelo menos um número de quatro dígitos - e, em seguida exclui de fox através do primeiro número de quatro dígitos.
-e "s/####//" , claro, limpa todas as sequências de #### que sobraram das linhas que contêm um número de quatro dígitos mas não fox .
Para remover também um espaço após o número, se houver um,
echo "The quick brown fox jumps over 42 lazy dogs in 2012 and 2013." \
| sed \
-e "s/[0-9]\{4\}/###/" \
-e "s/fox.*#### //" \
-e "s/fox.*####//" \
-e "s/####//"
Aviso: você pode adicionar g a todos os comandos s , mas, como isso ainda usa .* , que é a raiz do seu problema, ele ainda não manipulará
One fox jumps in 2012 and 2013, another fox will jump in 2014 and 2015.
do jeito que você provavelmente quer. E, é claro, você não deseja adicionar g a "s/[0-9]\{4\}/&####/" porque então injetará #### depois de todos número de quatro dígitos, derrotando todo o ponto. Então o "s/fox.*####//" acabará agindo como "s/fox.*[0-9]\{4\}//" (seu comando original com os caracteres não contribuintes removidos); ou seja, mudará
A rápida raposa marrom salta em 2012 e 2013.
para
A rápida raposa marrom salta em 2012 #### e 2013 ####.
e depois para
O castanho rápido.