Eliminar una fila que contiene 0 más de 'x' cantidad de veces

Eliminar una fila que contiene 0 más de 'x' cantidad de veces

Tengo un archivo grande separado por comas. Necesito filtrar filas que contienen x cantidad de columnas que contienen ceros (excluyendo la primera fila). Para simplificar, digamos que quiero filtrar filas con más de 4 ceros:

    gene,v1,v2,v3,v4,v5,v6,v7
    gene1,0,1,5,0,0,4,100
    gene2,1,0,0,0,5,210,2
    gene3,0,0,0,0,6,0,0

Volvería:

    gene,v1,v2,v3,v4,v5,v6,v7
    gene1,0,1,5,0,0,4,100
    gene2,1,0,0,0,5,210,2

Filtrando "gene3".

Esto es lo que he intentado (intentando y sin éxito usar ',0' como delimitador):

awk -F',0' 'NF<4 {print}' file.csv

Respuesta1

Con awk -F',0', tres copias de ,0se tomarán como tres.separadores, dando cuatrocamposen total. Entonces, si usas awk -F',0' 'NF<5 {print}'en su lugar, deberías ver las líneas correctas en el resultado.

,0también coincidirá con cadenas como 213,0123, que puede que desee o no tomar como separadores de cero.

Entonces, también puedes usarlo ,como separador de campos y contar los campos que tienen solo ese cero:

awk -F, '{z=0; for (i = 1 ; i <= NF ; i++) if ($i == 0) z++} z <= 4' file.csv

Respuesta2

También puedes resolver tu problema usando expresiones regulares y grep.

grep -Ev '(,0(,[^0,]+)*){4,}' file.csv

Lo probé en este archivo:

gene,v1,v2,v3,v4,v5,v6,v7
gene1,0,1,5,0,0,4,100
gene2,1,0,0,0,5,210,2
gene3,0,0,0,0,6,0,0
gene4,0,0,0,4,6,0,0
gene5,0,1,0,4,6,0,0

Hay algunas suposiciones:

  • ningún número distinto de cero comienza con cero,
  • los números cero contienen solo un cero,
  • todos los números son números enteros.

La expresión regular podría ampliarse para abordar estos casos si fuera necesario.

Respuesta3

Enfoque KISS, conawk

awk -F, '{c = 0; for(i=1; i<=NF; i++) {c += $i == "0" ? 1 : 0}} c <= 3' file.csv
    gene,v1,v2,v3,v4,v5,v6,v7
    gene1,0,1,5,0,0,4,100
    gene2,1,0,0,0,5,210,2

Conperl

perl -F, -ne 'print unless (grep { $_ eq "0" } @F) > 3' file.csv
    gene,v1,v2,v3,v4,v5,v6,v7
    gene1,0,1,5,0,0,4,100
    gene2,1,0,0,0,5,210,2

Respuesta4

Si todos los números son enteros, entonces usandoÑU awkque admite límites de palabras \<...\>, podrías hacerlo

gawk 'gsub(/\<0\>/, "0") <5' infile

información relacionada