So erhalten Sie die Nummer jedes Satzzeichens aus einer Datei

So erhalten Sie die Nummer jedes Satzzeichens aus einer Datei
grep '[".?!"]'

Gibt die Zeilen zurück, die eines davon haben, aber ich habe keine Ahnung, wie ich herausfinden kann, wie viele es in jeder Zeile sind, geschweige denn, wie viele ., ? und ! es gibt.

Antwort1

Dadurch wird eine Liste aller in der Datei gefundenen Satzzeichen gedruckt, ein Satzzeichen pro Zeile, jeweils gefolgt von der Anzahl dieser Zeichen in der Datei:

grep -o '[[:punct:]]' file | sort | uniq -c 

Ich teste gerne, indem ich /var/log/syslog ausführe. Meins hat momentan über 150.000 Zeilen.

Antwort2

Um die Gesamtzahl solcher Satzzeichen in einer Datei zu ermitteln, können Sie tralle anderen entfernen und dann wczählen:

tr -dc '.?!' | wc -c

Antwort3

Hier ist ein awk-Skript, das nach Zeilen sucht ., die , ?, oder enthalten !. Es druckt die Zeilennummer jeder Zeile, die eines dieser Satzzeichen enthält, die gefundene Nummer jedes Zeichens sowie die Gesamtzahl der Zeichen in dieser Zeile. Am Ende der Daten druckt es die Gesamtsummen.

Sie können ihm in der Befehlszeile mehrere Dateinamen übergeben und es verhält sich, als hätten Sie catalle Dateien zusammen verarbeitet. Es ist jedoch relativ einfach, dieses Skript so zu ändern, dass jede Datei einzeln verarbeitet wird.

#!/usr/bin/awk -f

# Count punctuation marks
# See http://unix.stackexchange.com/q/239894/88378
# Written by PM 2Ring 2015.10.131

BEGIN{
    FS = ""
    punc = ".?!"
    fmt = "%5s: .=%s, ?=%s, !=%s, all=%s\n"
}

/[.?!]+/{
    #print NR, $0, NF
    count[1] = count[2] = count[3] = 0
    for(i=1; i<=NF; i++)
    {
        n = index(punc, $i)
        if(n)
            count[n] += 1
    }
    all = count[1] + count[2] + count[3]
    printf fmt, NR, count[1], count[2], count[3], all
    for(i=1; i<=3; i++)
        total[i] += count[i]
}

END{
    all = total[1] + total[2] + total[3]
    printf fmt, "Total", total[1], total[2], total[3], all
}

Hier sind einige zufällige Daten, die ich zum Testen dieses Skripts verwendet habe:

Some test data
.a.?? .u o..ru. !!?aarl.?...t  s
e.?a.eli?.?s.. ?.r. s.t .e.a.le!
ti h  ..rs.  ?er.t. dn!t?.?.l.?t
?.n!rer e. d..!???? a .!..a.tit.
No punctuation
!.a.n..!isda!.o a!le.d..a.!sh.t?
?!?. ..!i  hi...h iii.?..a i hh?
.h r.u?....t..s !.. a  .li?hs !.
ia tso???.tr?t .hl..i.aids l.?.?
Bye-bye.

Und hier ist die generierte Ausgabe:

    2: .=10, ?=4, !=2, all=16
    3: .=11, ?=4, !=1, all=16
    4: .=8, ?=4, !=1, all=13
    5: .=9, ?=5, !=3, all=17
    7: .=10, ?=1, !=5, all=16
    8: .=9, ?=4, !=2, all=15
    9: .=12, ?=2, !=2, all=16
   10: .=7, ?=6, !=0, all=13
   11: .=1, ?=0, !=0, all=1
Total: .=77, ?=30, !=16, all=123

Getestet auf GNU Awk 3.1.7

Antwort4

sed -e'1{x;s/^/0ddsQsEsD[q]sq/p;x;}' \
    -e'/[^?!.]*\([?!.]\)[^?!.]*/!d;=' \
    -e's// l\11+s\1 /g;s/.*/pc0dds?s!s.&Q?E!D./' \
    -e's/\([QED]\)\(.\)/[l\21>q9P[\2=]Pl\2pl\1+9P[Total: ]Pps\1]x/g' |dc

Für jede Zeile, die einen dieser [?!.]Befehle enthält, wird zuerst die Zeilennummer ausgedruckt, dann die Anzahl der Zeichen in dieser Zeile und anschließend eine laufende Zählung für jede Zeile.

printf %s\\n \? \?\!. '' hey \? '' '' \! ...hey... .\!\? |
sed -e'1{x;s/^/0ddsQsEsD[q]sq/p;x;}' \
    -e'/[^?!.]*\([?!.]\)[^?!.]*/!d;=' \
    -e's// l\11+s\1 /g;s/.*/pc0dds?s!s.&Q?E!D./' \
    -e's/\([QED]\)\(.\)/[l\21>q9P[\2=]Pl\2pl\1+9P[Total: ]Pps\1]x/g' |dc

1
    ?=1
    Total: 1
2
    ?=1
    Total: 2
    !=1
    Total: 1
    .=1
    Total: 1
5
    ?=1
    Total: 3
8
    !=1
    Total: 2
9
    .=6
    Total: 7
10
    ?=1
    Total: 4
    !=1
    Total: 3
    .=1
    Total: 8

verwandte Informationen