Eu tenho um arquivo de texto em que cada linha das palavras é separada por vírgulas, assim:
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
Quero contar números diferentes de zero da segunda coluna usando apenas o comando sed
or grep
no Linux/UNIX.
Observação
Sem usar outros comandos:
cut -d',' -f2 < KAR_UBONA_UBONACT15_20150929_20150930_FEEDBACK.txt | grep -vcw 0
Mas não quero cut
só, preciso usar grep
.
Responder1
Você pode usar a -c
opção grep. E você pode remover todos os caracteres até a primeira vírgula e tudo a partir da segunda vírgula com sed
:
sed 's/^[^,]*,//;s/,.*//' < the_file | grep -c -E '[^0]'
EDIT: Este sed
comando faz o mesmo que o seu cut
comando, então você também deve poder usar o grep
comando original.
EDIT2: Se você quiser usar apenas um comando, você pode usar a resposta @cuonglm grp. Se você quiser usar apenasuma invocaçãodisso sed
será muito trabalho com rótulos para resumir a contagem de linhas no 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
Agora isso pode ser canalizado bc
ou você pode substituir o p
comando por alguma mágica complicada sed
para resumir esses números em sed
. Acredito ter ouvido dizer que sed
a operação está completa, então deveria ser possível.
Se você quiser usar apenasum programa( sed
) mas não se preocupe em invocá-lo várias vezes é muito mais fácil:
sed '/^[^,]*,0,.*/d' < the_file | sed -n '$='
Responder2
Com grep
:
grep -c '^[^,]*,[^0]' <file
Isso só funciona se a segunda coluna for formada como número inteiro, mas não -0
,. +0
Para um caso mais geral, consulteResposta de @Stéphane Chazelas.
Responder3
grep -c '^[^,]*,[-+0-9.]*[1-9]'
Isso deve abranger números expressos como 12
, -1
, 0e+12
, 01
, 0.0001
. Mas não para 0xFF
ou Inf
ou NaN
por exemplo, então isso ainda seria diferente do mais canônico:
POSIXLY_CORRECT=1 awk -v n=0 -F , '$2 != 0 {n++}; END{print n}'
Se sua entrada tiver números expressos nesse formato.
Para uma sed
única solução, você poderia fazer:
sed '/^[^,]*,[-+0-9]*[1-9]/!d' | sed -n '$='
Mas para uma solução com apenas uma sed
invocação, precisaríamos fazer a aritmética manualmente.
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;}'