Com o GNU sed :
sed 's/pattern//2g'
O 2 especifica que o segundo padrão e todo o restante g devem ser removidos. Então, isso vai manter o primeiro.
Eu tenho um arquivo de log com timestamps. Ocasionalmente, há vários timestamps em uma linha. Agora eu gostaria de remover todos os timestamps de uma linha, mas manter o primeiro.
Eu posso fazer s/pattern//2 , mas isso só remove a segunda ocorrência e sed não permite algo como s/pattern//2- .
Alguma sugestão?
Isso deve funcionar (substitua _ por outra coisa, caso ela entre em conflito com seus logs):
sed -e 's/pattern/_&/1' -e 's/\([^_]\)pattern//g' -e 's/_\(pattern\)//'
sed -e ':begin;s/pattern//2;t begin'
ou sem o sed goto:
sed -e 's/\(pattern\)/\n/;h;s/.*\n//;s/pattern//g;H;g;s/\n.*\n//'
As soluções genéricas para remover da posição enésima (3 por exemplo) são:
sed -e ':begin;s/pattern//4;t begin'
sed -e 's/\(pattern\)/\n/;h;s/.*\n//3;s/pattern//g;H;g;s/\n.*\n//'
Uma ligeira variação na resposta do @jillagre (modificado para robustez) poderia ser semelhante:
sed 's/p\(attern\)/p\n/;s///g;s/\n//'
... mas em alguns sed s você pode precisar substituir o n no lado direito da primeira instrução s/// ubstitution com um caractere literal \n ewline.
Tags sed