Remova letras e pontos de todas as linhas

4

Eu tenho um CSV que tem a saída de comandos time de programas diferentes, incluindo o ID da execução.

Portanto, meus arquivos contêm registros no seguinte formato:

ID,execution_time

Exemplo de registro:

345,0m0.047s

Eu só preciso do número de execuções e do número de segundos.

Portanto, o registro acima precisa ser

345,0047 (sem o "0m", o "." e o "s").

É possível conseguir isso?

    
por Jim Blum 02.07.2014 / 10:40

5 respostas

5

Aqui está a minha solução:

sed -i 's/[0-9]*m\|s\|\.//g' file.csv

Você pode pular a primeira linha, caso ela contenha o cabeçalho, assim:

sed -i '2,$s/[0-9]*m\|s\|\.//g' file.csv

Observe que a opção -i faz com que sed funcione "in place", alterando o arquivo original. Se você quiser criar um novo arquivo, use isto:

sed 's/[0-9]*m\|s\|\.//g' file.csv > new_file.csv
    
por kraxor 02.07.2014 / 10:56
10

E se houver minutos, hein? Aqui está uma que conta para isso, convertendo-os em segundos:

awk -F'[m,]' '{print  "," *60 + }' file.csv

E algumas demonstrações:

$ ... <(echo -e "345,0m0.047s\n345,1m0.047s\n345,1m2.047s")
345,0.047
345,60.047
345,62.047

Não sei por que você deseja remover o ponto decimal, mas pode passar a saída por meio de sed 's/\.//g' , se você realmente precisar disso:

$ ... <(echo -e "345,0m0.047s\n345,1m0.047s\n345,1m2.047s") | sed 's/\.//g'
345,0047
345,60047
345,62047

Eugh.

E - presumindo que esta é uma saída time - e se o valor contiver horas ou até dias? Eu brinquei um pouco e inventei essa pequena beleza:

awk -F'[dhms,]' 'BEGIN{split("1 60 3600 86400", T, " ")}{t=0; for (i=NF-1; i>1; i--) t+=T[NF-i]*$i; printf("%s,%.3f\n", , t)}'

Isso manipulará os seguintes formatos: *s *m*s *h*m*s e *d*h*m*s e converterá todos em segundos (até três casas decimais). Demora obrigatória:

$ ... <(echo -e "345,1.2s\n345,12m5s\n345,1h2m5s\n345,1d2h1m2.047s")
345,1.200
345,725.000
345,3725.000
345,93662.047
    
por Oli 02.07.2014 / 11:00
4

Deve ser:

sed 's/m0\.\(.*\)s$//g'

    
por Yaron 02.07.2014 / 10:44
1

Outro através do awk,

awk -F, -v OFS="," '{gsub(/0m/,"",);gsub(/\./,"",);gsub(/s/,"",); print ,}' file

Exemplo:

$ echo '345,0m0.047s' | awk -F, -v OFS="," '{gsub(/0m/,"",);gsub(/\./,"",);gsub(/s/,"",); print ,}'
345,0047

E o apropriado,

$ echo '345,52m0.047s' | awk -F, -v OFS="," '{gsub(/^.*?m/,"",);gsub(/\./,"",);gsub(/s/,"",); print ,}'
345,0047
    
por Avinash Raj 02.07.2014 / 11:08
1

A resposta de @kraxor usa sed para remover "todo o resto" da linha e, em seguida, mostra a linha.

Mas - o que é realmente "todo o resto" ? Aqui temos uma ideia, pelo menos, de uma linha de amostra. Mas o que quando recebemos uma linha de cabeçalho CSV? O que remover?
Em geral, não sabemos.

Portanto, é melhor realmente mostrar os dados que queremos mostrar !

echo '345,0m0.047s' | sed -n -r 's/^(.*),.*[^0-9]([0-9]*)\.(.*)s$/,/p'

345,0047

Funciona até agora!

O que isso faz?
Nós não imprimimos a linha normalmente ( -n )
(e ative as "expressões regulares estendidas" mais agradáveis ( -r )) Agora, procure o ID, segundo e segundo fracionário,
e se os encontramos, coloque-os na linha, no formato correto (adicionando ","),
e imprima a linha recém criada.

Agora, algumas outras entradas, bastante normais , com duas linhas de dados:

ID,execution_time
123, Oops a comment0m0.0333s
345,0m0.047s

Huh ?! Parece com dados do mundo real , na verdade!

echo "ID,execution_time\n123, Oops a comment0m0.0333s\n345,0m0.047s" | sed -r -n 's/^(.*),.*[^0-9]([0-9]*)\.(.*)s$/,/p'

123,00333
345,0047

Parece legal e está certo!


Para mostrar que tem algum mérito de fazer isso, compararei com a resposta anterior:

echo "ID,execution_time\n123, Oops a comment0m0.0333s\n345,0m0.047s" | sed 's/[0-9]*m\|s\|\.//g'

ID,execution_tie
123, Oop a coent00333
345,0047

Ok, as linhas de dados limpas e reais passaram bem; Mas as outras partes, não tanto (note o cabeçalho não foi apenas passado, mas cortado.).

(Note que há uma solução para ignorar explicitamente a linha de cabeçalho (ou talvez a primeira linha de dados, sabemos?))

    
por Volker Siegel 02.07.2014 / 18:11