Grep: cuenta el número de coincidencias por línea


26

Estoy tratando de obtener el número de coincidencias (en este caso, ocurrencias de {o }) en cada línea de un archivo .tex.

Sé que la -obandera solo devuelve la coincidencia, pero devuelve cada coincidencia en una nueva línea, incluso combinada con la -nbandera. No sé de nada con lo que pueda canalizar esto para contar las repeticiones. La -cbandera solo devuelve el número total de coincidencias en todo el archivo, ¿tal vez podría canalizar una línea a la vez para grep?

Respuestas:


27
grep -o -n '[{}]' <filename> | cut -d : -f 1 | uniq -c

La salida será algo así como:

3 1
1 2

Significa 3 ocurrencias en la primera línea y 1 en la segunda.

Tomado de /programming//a/15366097/3378354 .


Gracias: Google encontró muchos éxitos de expresiones regulares en SU, pero no ese en SO, que ni siquiera parece tener una etiqueta de expresiones regulares. No sortes estrictamente necesario ya que la salida de grep está ordenada por número de línea, pero supongo que es una buena práctica antes uniq.
Chris H

2
Probablemente no etiquetado regexporque la expresión regular es la parte fácil.
Tom Zych

¿Es realmente necesario sort -n? ¿No sale en orden de número de línea de todos modos?
Tom Zych

Tienes razón, sort -nno es necesario. Gracias.
Moebius

@TomZych, resultó que tenías razón, pero si hubiera sabido que podría no haberte preguntado. Sin embargo, el salto mental de grep a tag: regex fue quizás demasiado.
Chris H

3

Después de leer varias soluciones, creo que este es el enfoque más fácil para el problema:

while read i; do echo $i |grep -o "matchingString"| wc -l;  done < input.txt

3
La mejor solución, en mi opinión. Podría ser aún más simplificado, reduciendo por un tubo: grep -o "matchingString" <<< $i | wc -l.
Benjamin

1
Sin embargo
Rahul

1

¿Está usando grepun requisito? Aquí hay una alternativa:

sed 's / [^ {}] // g' tu_archivo | awk '{print NR, length}'

Las sedtiras fuera todos los caracteres distintos de {y } (es decir, dejando sólo {y }caracteres), y luego los awkcuenta los caracteres en cada línea (que son sólo las {y }caracteres). Para suprimir líneas sin coincidencias,

sed 's / [^ {}] // g' tu_archivo | awk '/./ {print NR, length}'

Tenga en cuenta que mi solución asume (requiere) que las cadenas que está buscando son caracteres individuales. La respuesta de Moebius se adapta más fácilmente a cadenas de caracteres múltiples. Además, ninguna de nuestras respuestas excluye las ocurrencias citadas o escapadas de los caracteres / cadenas de interés; p.ej,

{ "nullfunc() {}" }

se consideraría que contiene cuatro caracteres de llaves.


grepen realidad no era un requisito, fue justo donde comencé a buscar una solución, porque me dio algo cercano. Nunca he tenido necesidad de awk, así que si no hubiera usado la respuesta anterior, habría usado esto como una oportunidad para experimentar, todavía puedo. Lo que no pude dejar claro (pero no afecta a ninguna de las respuestas) es que quería ejecutar el script una vez por paréntesis, para ayudarme a rastrear una falta de coincidencia (en la fuente LaTeX, aquí para una tabla) donde ocurren la mayoría de los pares en Una sola línea.
Chris H

No estoy muy seguro de lo que quiere decir con "ejecutar el script una vez por paréntesis", pero si desea rastrear una falta de coincidencia de llaves, es posible que desee probar algo como sed 's/{[^{}]*}//g' your_file | grep –n '[{}]', donde las sedtiras se emparejan. Si tiene pares anidados, use sed 's/{[^{}]*}//g;s/{[^{}]*}//g;s/{[^{}]*}//g;…' …, repitiendo s/{[^{}]*}//gtantas veces como su anidación más profunda.
Scott

Me refería a ejecutar 'sed' s / [^}] // g 'your_file | awk '{print NR, length}' y 's / [^ {] // g' your_file | awk '{print NR, length}'. De hecho, tengo anidamiento, y trabajar en el nivel más profundo parecía una tarea. Convertir muchas líneas en un puñado (hay algunos casos en los que los corchetes solo coinciden en varias líneas por razones válidas) funcionó bien (uso jedit que resalta el corchete correspondiente, para cualquier tipo de corchete que entienda), así que realmente lo hice solo necesito reducirlo).
Chris H
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.