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 sed
o grep
en 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 -c
opció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 sed
comando hace lo mismo que su cut
comando, por lo que también debería poder usar su grep
comando original.
EDITAR2: Si desea usar solo un comando, puede usar la respuesta @cuonglm grp. Si quieres usar solouna invocaciónEsto sed
requerirá 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 bc
o puede reemplazar el p
comando con alguna sed
magia complicada para resumir estos números sed
. Creo que he oído que sed
se 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
. +0
Para 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.0001
Pero no por 0xFF
o Inf
por NaN
ejemplo, 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 sed
invocació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;}'