Ich habe eine Textdatei, in der die Wörter in jeder Zeile durch Kommas getrennt sind, wie folgt:
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
Ich möchte die von Null verschiedenen Zahlen der zweiten Spalte nur mit dem sed
oder grep
Befehl in Linux/UNIX zählen.
Notiz
Ohne andere Befehle zu verwenden:
cut -d',' -f2 < KAR_UBONA_UBONACT15_20150929_20150930_FEEDBACK.txt | grep -vcw 0
Aber ich will nicht cut
nur, ich muss verwenden grep
.
Antwort1
Sie können die Option von grep verwenden -c
. Und Sie können alle Zeichen bis zum ersten Komma und alles ab dem zweiten Komma mit entfernen sed
:
sed 's/^[^,]*,//;s/,.*//' < the_file | grep -c -E '[^0]'
BEARBEITEN: Dieser sed
Befehl macht dasselbe wie Ihr cut
Befehl, Sie sollten also auch Ihren ursprünglichen Befehl verwenden können grep
.
EDIT2: Wenn Sie nur einen Befehl verwenden möchten, können Sie @cuonglm grp answer verwenden. Wenn Sie nureine AnrufungEs sed
wird viel Arbeit mit Beschriftungen erfordern, um am Ende die Zeilenanzahl zusammenzufassen.
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
Dies kann nun weitergeleitet werden, bc
oder Sie können den p
Befehl durch etwas komplizierte sed
Magie ersetzen, um diese Zahlen in zusammenzufassen sed
. Ich glaube, ich habe gehört, dass sed
dies Turing-vollständig ist, also sollte es möglich sein.
Wenn Sie nur verwenden möchtenein Programm( sed
), aber wenn Sie es nicht mehrmals aufrufen möchten, ist es viel einfacher:
sed '/^[^,]*,0,.*/d' < the_file | sed -n '$='
Antwort2
Mit grep
:
grep -c '^[^,]*,[^0]' <file
Das funktioniert nur, wenn die zweite Spalte wie eine Ganzzahl, aber nicht wie -0
, gebildet wird +0
. Für allgemeinere Fälle sieheAntwort von @Stéphane Chazelas.
Antwort3
grep -c '^[^,]*,[-+0-9.]*[1-9]'
Dies sollte für Zahlen gelten, die als 12
, -1
, 0e+12
, 01
, ausgedrückt werden 0.0001
. Aber nicht für 0xFF
oder Inf
oder NaN
beispielsweise. Dies wäre also immer noch anders als das kanonischere:
POSIXLY_CORRECT=1 awk -v n=0 -F , '$2 != 0 {n++}; END{print n}'
Wenn Ihre Eingabe Zahlen enthält, die in einem solchen Format ausgedrückt sind.
Als sed
einzige Lösung könnten Sie Folgendes tun:
sed '/^[^,]*,[-+0-9]*[1-9]/!d' | sed -n '$='
Für eine Lösung mit nur einem sed
Aufruf müssten wir die Berechnung jedoch manuell durchführen.
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;}'