Как получить число знаков препинания из файла

grep '[".?!"]' 

Возвращает строки, которые имеют один из них, но я не знаю, как рассказать, сколько в каждой строке, не говоря уже о том, сколько.,? И! есть.

Это напечатает список всех символов пунктуации, найденных в файле, по одному символу пунктуации в строке, каждый из которых будет подсчитываться по количеству символов в файле:

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

Мне нравится тестировать, запустив / var / log / syslog, у меня есть более 150 000 строк прямо сейчас.

Чтобы найти общее количество таких знаков препинания в файле, вы можете использовать tr для удаления всех остальных, затем wc для подсчета:

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

Вот скрипт awk, который ищет строки, содержащие . , ? , или ! , Он печатает номер строки каждой строки, содержащей любую из этих знаков препинания, номер, найденный для каждой марки, плюс общее количество меток на этой строке. В конце данных он печатает грандиозные итоги.

Вы можете передать ему несколько имен файлов в командной строке, и он будет вести себя так, как если бы вы котали все файлы вместе, но довольно легко изменить этот скрипт для обработки каждого файла по отдельности.

 #!/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 } 

Вот некоторые случайные данные, которые я использовал для проверки этого скрипта:

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

И вот результат, который был сгенерирован:

  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 

Протестировано на GNU Awk 3.1.7

 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 

Для любой строки, содержащей любую из [?!.] , Эта команда сначала напечатает номер строки, затем количество символов в этой строке, а затем текущую таблицу для каждого.

 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