
grep '[".?!"]'
Devuelve las líneas que tienen uno de estos, pero no tengo idea de cómo saber cuántos hay en cada línea, y mucho menos cuántos ., ? y ! hay.
Respuesta1
Esto imprimirá una lista de todos los caracteres de puntuación que se encuentran en el archivo, un carácter de puntuación por línea, cada uno precedido por el recuento de esos caracteres en el archivo:
grep -o '[[:punct:]]' file | sort | uniq -c
Me gusta probar ejecutando /var/log/syslog, el mío tiene más de 150.000 líneas en este momento.
Respuesta2
Para encontrar el número total de dichos signos de puntuación en un archivo, puede usar tr
para eliminar todos los demás y luego wc
contarlos:
tr -dc '.?!' | wc -c
Respuesta3
Aquí hay un script awk que busca líneas que contengan .
, ?
o !
. Imprime el número de línea de cada línea que contiene cualquiera de esos signos de puntuación, el número encontrado de cada marca, más el número total de marcas en esa línea. Al final de los datos, imprime los totales generales.
Puede pasarle varios nombres de archivos en la línea de comando y se comportará como si hubiera cat
reunido todos los archivos, pero es bastante fácil modificar este script para procesar cada archivo individualmente.
#!/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
}
Aquí hay algunos datos aleatorios que utilicé para probar este script:
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.
Y aquí está el resultado que se generó:
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
Probado en GNU Awk 3.1.7
Respuesta4
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
Para cualquier línea que contenga alguno de [?!.]
esos comandos, primero se imprimirá su número de línea, luego el recuento de los caracteres en esa línea y luego un recuento acumulado para cada uno.
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