
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 tr
alle anderen entfernen und dann wc
zä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 cat
alle 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