Подсчитайте ненулевые числа для каждой строки второго столбца в текстовом файле

У меня есть текстовый файл, в котором каждая строка слов разделяется запятыми, например:

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 

Я хочу подсчитать ненулевые числа второго столбца, используя только команду sed или grep в Linux / UNIX.

Заметка

Без использования других команд:

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

Но я не хочу cut только, мне нужно использовать grep .

Вы можете использовать параметр -c grep. И вы можете удалить все символы до первой запятой и все, начиная с второй запятой, с помощью sed :

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

EDIT: эта команда sed выполняет то же самое, что и ваша команда cut поэтому вы также можете использовать свою оригинальную команду grep .

EDIT2: Если вы хотите использовать только одну команду, вы можете использовать ответ @cuonglm grp. Если вы хотите использовать только один вызов sed будет много работы с ярлыками, чтобы суммировать количество строк в конце.

 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 

Теперь это можно передать на bc или вы можете заменить команду p на некоторую сложную магию sed чтобы суммировать эти числа в sed . По-моему, я слышал, что sed завершен, так что это должно быть возможно.

Если вы хотите использовать только одну программу ( sed ), но не хотите ее несколько раз ссылаться на нее:

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

С grep :

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

Это работает, только если 2-й столбец сформирован как целое, но не -0 , +0 . Для более общего случая см . Ответ @ Stéphane Chazelas .

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

Это должно охватывать числа, выраженные как 12 , -1 , 0e+12 , 01 , 0.0001 . Но не для 0xFF или Inf или NaN например, так что все равно будет отличаться от более канонического:

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

Если ваш ввод содержит цифры, выраженные в таком формате.

Для решения sed только вы можете:

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

Но для решения с одним вызовом sed нам нужно выполнить арифметику вручную.

 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;}'