Esta é uma variação da resposta do slhck que lida corretamente com um campo de extensão vazio (e evita a substituição falsa de um ponto que possa ter existido intencionalmente no segundo ou terceiro campo):
sed 's/^\([^;]*\);\([^;]*\)//;ta;:a;s/^[^;]\+;;/&/;t;s/;/./' inputfile
Não é necessário usar um terceiro grupo de captura. Essa resposta funciona sem ela. Não é necessário escapar do ponto no lado direito do comando substituto.
Aqui está uma explicação do meu script:
- capture os dois primeiros campos, excluindo os pontos e vírgulas que os delimitam.
-
ta;:a
- se um substituto for bem-sucedido, então ramifique para o rótulo:a
que imediatamente se segue - isso efetivamente limpa o sinalizador "sucesso" -
s/^[^;]\+;;/&/
- substitui uma sequência de semicolons seguida por dois pontos e vírgulas (os primeiro e segundo campos concatenados seguidos por um terceiro campo vazio) consigo mesmo - é um não-op, mas define o sinalizador "sucesso". -
t
- se a última substituição foi bem sucedida (o terceiro campo está vazio), pule para o final do processamento da linha atual (já que nenhum rótulo foi especificado) -
s/;/./
- se chegamos a este ponto (o terceiro campo não estava vazio ), substitua o ponto-e-vírgula por um ponto.