Como está marcado com o awk
awk -F", *" 'x!=||>=y+10{y=;print}{x=}' file
Test1, 0.0, 1
Test1, 10.0, 3
Test2, 0.1, 1
Test2, 11.0, 7
Gostaria de remover algumas linhas de um arquivo csv.
As regras são simples o suficiente (manter linha se):
Fonte
Test1, 0.0, 1
Test1, 0.2, 1
Test1, 10.0, 3
Test2, 0.1, 1
Test2, 0.3, 3
Test2, 1.0, 5
Test2, 11.0, 7
Resultado
Test1, 0.0, 1
Test1, 10.0, 3
Test2, 0.1, 1
Test2, 11.0, 7
Eu estava pensando em fazer isso com o awk e algumas instruções if, mas não tenho certeza se posso fazer uma variável que seja transferida entre o processamento do registro.
EDIT: isso foi escondido na seção de comentários (de mim):
Acabei de descobrir que as variáveis são utilizáveis entre registros. Algo que não funciona como o C. Vou remover essa pergunta a menos que alguém dê uma resposta que considere útil para os outros ou alguém me peça para fornecer a resposta.
Como está marcado com o awk
awk -F", *" 'x!=||>=y+10{y=;print}{x=}' file
Test1, 0.0, 1
Test1, 10.0, 3
Test2, 0.1, 1
Test2, 11.0, 7
Usando um script Python:
#! /usr/bin/env python3
import sys
with open (sys.argv[1]) as f:
rows=[list(map(str.strip, line.split(','))) for line in f.readlines()]
result=rows[0:1]
for r in rows:
if r[0] != result[-1][0] or float(r[1]) >= float(result[-1][1])+10:
result.append(r)
print("\n".join([",".join(res) for res in result]))
Copie o script acima e cole-o em um arquivo chamado csvfilter.py
, por exemplo.
Torne-o executável usando chmod +x csvfilter.py
.
Em seguida, você pode executá-lo a partir da linha de comando com o arquivo csv para processar (salvei seu exemplo da pergunta como source.csv
) como argumento:
$ ./csvfilter.py source.csv
Test1,0.0,1
Test1,10.0,3
Test2,0.1,1
Test2,11.0,7
O script não modifica o arquivo original, apenas imprime a nova versão na saída padrão. Além disso, qualquer formatação anterior usando espaços será descartada.
Para substituir o arquivo original pela versão modificada, redirecione a saída de volta ao arquivo original:
$ ./csvfilter.py source.csv > source.csv
Você também pode salvar a versão modificada como um arquivo:
$ ./csvfilter.py source.csv > modified.csv
Usando o Perl:
perl -lane 'if($.==1||"$F[0]"ne"$F0"||$F[1]>=$F1+10){print;$F1=@F[1]}$F0=@F[0]' file
Expandido:
if($. == 1 || "$F[0]" ne "$F0" || $F[1] >= $F1 + 10){
print;
$F1 = @F[1]
}
$F0 = @F[0]
if($.==1||"$F[0]"ne"$F0"||$F[1]>=$F1+10){print;$F1=@F[1]}
: se o número da linha atual for 1
, o primeiro campo da linha atual é igual ao primeiro campo da linha anterior ou o segundo campo da linha atual é maior ou igual ao segundo campo da linha anterior, imprime a linha atual e atribui o valor do segundo campo da linha atual para F1
; $F0=@F[0]
: atribui o valor do primeiro campo da linha atual a F0
; % cat file
Test1, 0.0, 1
Test1, 0.2, 1
Test1, 10.0, 3
Test2, 0.1, 1
Test2, 0.3, 3
Test2, 1.0, 5
Test2, 11.0, 7
% perl -lane 'if($.==1||"$F[0]"ne"$F0"||$F[1]>=$F1+10){print;$F1=@F[1]}$F0=@F[0]' file
Test1, 0.0, 1
Test1, 10.0, 3
Test2, 0.1, 1
Test2, 11.0, 7