Zählen Sie für jede Zeile einer zweiten Spalte in einer Textdatei Zahlen ungleich Null

Zählen Sie für jede Zeile einer zweiten Spalte in einer Textdatei Zahlen ungleich Null

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 sedoder grepBefehl 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 cutnur, 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 sedBefehl macht dasselbe wie Ihr cutBefehl, 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 sedwird 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, bcoder Sie können den pBefehl durch etwas komplizierte sedMagie ersetzen, um diese Zahlen in zusammenzufassen sed. Ich glaube, ich habe gehört, dass seddies 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 0xFFoder Infoder NaNbeispielsweise. 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 sedeinzige Lösung könnten Sie Folgendes tun:

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

Für eine Lösung mit nur einem sedAufruf 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;}'

verwandte Informationen