Remover um retorno de carro com sed

1

Eu tenho um arquivo CSV grande. Um dos campos contém um erro. Este erro aparece como uma nova linha no arquivo.

Desde então eu tenho usado o notepad ++ com este comando para corrigir o problema:

\r";" => ";"

Como posso fazer o mesmo com sed?

Eu já tentei

sed -i 's/\r";"/";"/g' /path/file.csv
sed -i 's/^";"/";"/g' /path/file.csv

sem sucesso, alguém aqui provavelmente conhece o comando certo

    
por erave 30.11.2014 / 12:53

2 respostas

3

É importante entender que o sed funciona linha por linha. O que o sed faz é basicamente: ler uma linha em seu buffer sem a nova linha , executar seus comandos no buffer, imprimir o buffer (desde que você não tenha especificado o -n flag), ler o próximo Então, para mesclar duas linhas com sed, é necessário forçar explicitamente que o sed trate mais de uma linha de cada vez. Para fazer isso, os comandos N , P e D são seus amigos.

Agora, para o seu problema específico, para fornecer uma resposta específica e testada, seria necessário inserir um tipo específico de entrada, mas aqui estão alguns exemplos do que pode ser feito:

Isso mesclará todas as duas linhas juntas:

sed $'N;s/[\n\r]//g'

ou se você tiver certeza de ter sempre \ r \ n terminações de linha:

sed 'N;s/.\n//'

Para uma abordagem mais personalizada do que eu entendi da sua pergunta, embora não seja a melhor solução, isso deve fazer o trabalho, desde que você use o bash ou outro shell que suporte o C escape via $'str' construct:

sed $':l;N;/\r\n";"/{;s/\r\n";"/";"/g;n;};bl'

ou sem a construção de escape no estilo C e com \ r \ n terminações de linha (não negociáveis):

sed ':l;N;/\n";"/{;s/.\n";"/";"/g;n;};bl'

O que ele faz é basicamente acrescentar a próxima linha ao seu buffer ( N ) e testar a string que você quer ( /\r\n";"/ ). O script faz um loop ( bl - > ramifica para rotular :l definido no início), desde que não encontre uma correspondência. Quando uma correspondência é encontrada, ele executa o script sed entre as chaves: substitui todas as ocorrências de \r\n";" por ";" ( s/\r\n";"/";"/g ) e libera o buffer e insere a próxima linha ( n ).

É claro que, se o arquivo for grande e os "erros" não forem frequentes, isso poderá ser executado por muito tempo e ter muita memória. Se este for o caso, outro algoritmo poderia ser usado, mas eu precisaria ter um exemplo melhor do que você está enfrentando para ter certeza de que entendi seu problema corretamente.

Além disso, se você quiser saber um pouco mais sobre o sed, recomendo enfaticamente este site que pode não tem a melhor cor de fundo, mas é o melhor tutorial de sed lá IMO.

    
por 02.12.2014 / 01:12
0

Se você pode viver com uma solução de perl:

perl -pe 's/\r";"/";"/g' foo.csv >foo_r.csv
    
por 02.12.2014 / 01:59