Cuente números distintos de cero para cada fila de una segunda columna en un archivo de texto

Cuente números distintos de cero para cada fila de una segunda columna en un archivo de texto

Tengo un archivo de texto en el que las palabras de cada línea están separadas por comas, como esta:

7022122465,0,\N,,0,2015-09-29 10:48:33
7022597642,0,\N,,0,2015-09-29 10:48:33
7022848906,0,\N,,0,2015-09-29 10:48:33
7022848906,5,\N,,0,2015-09-29 10:48:33
7022848906,55,\N,,0,2015-09-29 10:48:33
.....................................etc

Quiero contar números distintos de cero de la segunda columna usando solo el comando sedo grepen Linux/UNIX.

Nota

Sin usar otros comandos:

cut -d',' -f2 < KAR_UBONA_UBONACT15_20150929_20150930_FEEDBACK.txt | grep -vcw 0

Pero no solo quiero cut, necesito usar grep.

Respuesta1

Puedes usar la -copción de grep. Y puedes eliminar todos los caracteres hasta la primera coma y todo lo que esté a partir de la segunda coma con sed:

sed 's/^[^,]*,//;s/,.*//' < the_file | grep -c -E '[^0]'

EDITAR: este sedcomando hace lo mismo que su cutcomando, por lo que también debería poder usar su grepcomando original.

EDITAR2: Si desea usar solo un comando, puede usar la respuesta @cuonglm grp. Si quieres usar solouna invocaciónEsto sedrequerirá mucho trabajo con las etiquetas para resumir el recuento de líneas al final.

sed -E -n '
    s/^[^,]*,[^0,]+,.*/+1/   # replace the lines we are interested in with "+1"
    T delete_line            # if we did not do a substitution right now we jump to "delete_line"
    H                        # we did not jump (so we did the substitution and append the "+1" to the hold space
    : delete_line            # the label, here we do nothing (silently drop the current line)
    $ {                      # on the last line we ...
        s/.*/0/              # replace the whole line with "0"
        G                    # append the hold space (all the "+1" from before")
        s/\n//g              # remove all newlines
        p                    # print the line
    }' < the_file

Esto ahora se puede canalizar bco puede reemplazar el pcomando con alguna sedmagia complicada para resumir estos números sed. Creo que he oído que sedse está completando, por lo que debería ser posible.

Si solo quieres usarun programa( sed) pero no importa invocarlo varias veces es mucho más fácil:

sed '/^[^,]*,0,.*/d' < the_file | sed -n '$='

Respuesta2

Con grep:

grep -c '^[^,]*,[^0]' <file

Eso solo funciona si la segunda columna se forma como un número entero, pero no -0. +0Para un caso más general, consulteLa respuesta de @Stéphane Chazelas.

Respuesta3

grep -c '^[^,]*,[-+0-9.]*[1-9]'

Eso debería cubrir los números expresados ​​como 12, -1, 0e+12, 01. 0.0001Pero no por 0xFFo Infpor NaNejemplo, por lo que aún sería diferente de lo más canónico:

POSIXLY_CORRECT=1 awk -v n=0 -F , '$2 != 0 {n++}; END{print n}'

Si su entrada tiene números expresados ​​en dicho formato.

Para una sedúnica solución, podrías hacer:

sed '/^[^,]*,[-+0-9]*[1-9]/!d' | sed -n '$='

Pero para una solución con una sola sedinvocación, necesitaríamos hacer la aritmética a mano.

sed -n '
  1{x;s/$/0,:0123456789,0/;x;}
  /^[^,]*,[-+0-9]*[1-9]/ {
    x;:1
    s/^,/1/;s/\(.\),\(.*:.*\1\(,*.\)\)/\3\2/;t1
    s/:/,:/
    x
  }
  ${x;s/,.*//p;}'

información relacionada