sed: exclui todas as ocorrências de uma string, exceto a primeira

13

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?

    
por Folkert van Heusden 08.08.2011 / 08:58

4 respostas

4

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.

    
por 18.12.2014 / 09:24
7

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\)//'
    
por 08.08.2011 / 13:41
5
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//'
    
por 08.08.2011 / 13:50
1

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.

    
por 19.12.2014 / 14:32

Tags