2012-02-16 28 views
8

Tengo un enorme archivo con direcciones de correo electrónico y me gustaría contar cuántos de ellos están en este archivo. ¿Cómo puedo hacer eso usando la línea de comando de Windows?¿Cómo encontrar el número de ocurrencias de una cadena en un archivo usando la línea de comandos de Windows?

He intentado esto pero solo imprime las líneas correspondientes. (Por cierto: todos los correos electrónicos están contenidos en una sola línea)

findstr /c:"@" mail.txt

Respuesta

11

El uso de lo que tiene, que podrían canalizar los resultados a través de un find. He visto algo como esto usado de vez en cuando.

findstr /c:"@" mail.txt | find /c /v "GarbageStringDefNotInYourResults" 

Así que usted está contando las líneas resultantes de su comando findstr que no tienen la cadena de basura en él. Es un truco, pero podría funcionar para ti. Alternativamente, solo use el find /c en la cadena que realmente le interesa. Por último, mencionó una dirección por línea, por lo que en este caso lo anterior funciona, pero varias direcciones por línea y esto se rompe.

+0

Devuelve 1 también. – Patryk

+0

@Patryk, mi error, leí mal que todos los correos electrónicos estaban en cada uno en su propia línea. Revisaremos –

0

Encontré esto en la red. Ver si funciona:

findstr /R /N "^.*certainString.*$" file.txt | find /c "@" 
+0

Gracias por eso pero 'findstr/R/N" ^. * @. * $ "Mail.txt | find/c "@" 'devuelve 1 para mí. Tal vez sea un problema con los resultados en una sola línea. – Patryk

1

Me gustaría instalar las herramientas de UNIX en su sistema (útil en cualquier caso :-), entonces es muy simple - por ejemplo, mirar aquí:

Count the number of occurrences of a string using sed?

(Utilizando awk:

awk '$1 ~ /title/ {++c} END {print c}' FS=: myFile.txt 

).

, usted puede obtener las herramientas de Windows UNIX aquí:

http://unxutils.sourceforge.net/

+0

Simplemente 'grep -c -o @' sería suficiente (o 'grep -o @ | wc -l' si tiene un buggy' grep' que no tiene DTRT). – tripleee

+0

También el script 'awk' cuenta líneas con ocurrencias, no ocurrencias reales. No es difícil de arreglar, pero es más fácil usar 'grep -o'. – tripleee

+0

@tripleee Sé que puedo usar las herramientas de Unix (que es mucho más fácil de usar) pero me gustaría hacer con la línea de comandos de Windows. – Patryk

0

Así es como lo hago, utilizando una condición AND con FINDSTR (a contar el número de errores en un archivo de registro):

SET COUNT=0 
FOR /F "tokens=4*" %%a IN ('TYPE "soapui.log" ^| FINDSTR.exe /I /R^ 
/C:"Assertion" ^| FINDSTR.exe /I /R /C:"has status VALID"') DO (
    :: counts number of lines containing both "Assertion" and "has status VALID" 
    SET /A COUNT+=1 
) 
SET /A PASSNUM=%COUNT% 

NOTA: Esto cuenta "cantidad de líneas que contienen cadena coincidente" en lugar de "cantidad total de ocurrencias en el archivo".

3

Puede ser que sea un poco tarde, pero la siguiente secuencia de comandos funcionó para mí (el archivo fuente contenía caracteres de comillas, esta es la razón por la que utilicé el parámetro 'usebackq'). El signo de intercalación (^) actúa como carácter de escape en el lenguaje de secuencias de comandos de Windows.

@setlocal enableextensions enabledelayedexpansion  
SET TOTAL=0 
FOR /F "usebackq tokens=*" %%I IN (file.txt) do (
    SET LN=%%I 
    FOR %%J IN ("!LN!") do (
     FOR /F %%K IN ('ECHO %%J ^| FIND /I /C "searchPhrase"') DO (
      @SET /A TOTAL=!TOTAL!+%%K 
     ) 
    ) 
) 
ECHO Number of occurences is !TOTAL! 
+0

Confirmó que esto funciona. –

1

solución muy simple:

grep -o "@" mail.txt | grep -c . 

recordar un punto al final de la línea!

Aquí es poco manera más comprensible:

grep -o "@" mail.txt | grep -c "@" 

Primera grep selecciona sólo "@" cuerdas y poner cada uno en la nueva línea.

Segundo grep cuenta líneas (o líneas con @).

La utilidad grep se puede instalar desde GnuWin project o desde WinGrep sitios. Es un filtro de texto muy pequeño y seguro. El grep es uno de los comandos Unix/Linux más útiles y lo uso tanto en Linux como en Windows a diario. El Windows findstr es bueno, pero no tiene características como grep.

La instalación del grep en Windows será una de las mejores decisiones si le gusta la CLI o los scripts por lotes.

2

Por qué no simplemente el uso de este (esto determina el número de líneas que contienen (al menos) un Char @.):

find /C "@" "mail.txt" 

Ejemplo de salida:

---------- MAIL.TXT: 96 

Para evitar el nombre del archivo en la salida, cámbielo a esto:

salida
find /C "@" < "mail.txt" 

Ejemplo:

96 

para capturar el número resultante y lo almacena en una variable, utilice este (modificar %N a %%N en un archivo por lotes):

set "NUM=0" 
for /F %N in ('find /C "@" ^< "mail.txt"') do set "NUM=%N" 
echo %NUM% 
-1

Usar este :

type file.txt | find /i "@" /c 
+0

Si bien este fragmento de código puede resolver la pregunta, [incluyendo una explicación] (http://meta.stackexchange.com/questions/114762/explaining-entirely-código-basado-respuestas) realmente ayuda a mejorar la calidad de su publicación. Recuerde que está respondiendo la pregunta para lectores en el futuro, y esas personas podrían no conocer los motivos de su sugerencia de código. –

1

OK - camino tarde a la mesa, pero ... parece que muchos de los encuestados perdieron la especificación original que todas las direcciones de correo electrónico se producen en 1 línea. Esto significa que a menos que introduzca un CRLF con cada aparición del símbolo @, sus sugerencias para usar variantes de FINDSTR/c no ayudarán.

Entre las herramientas de Unix para DOS se encuentra el muy potente SED.exe. Buscalo en Google. Mece RegEx. He aquí una sugerencia:

find "@" datafile.txt | find "@" | sed "s/@/@\n/g" | find /n "@" | SED "s/\[\(.*\)\].*/Set \/a NumFound=\1/">CountChars.bat 

Explicación: (suponiendo que el archivo con los datos se denomina "Datafile.txt") 1) La primera FIND incluye 3 líneas de información de la cabecera, lo que arroja un enfoque de línea de conteo, de modo que canalice los resultados a un segundo hallazgo (idéntico) para quitar la información del encabezado no deseado.

2) Transfiera los resultados anteriores a SED, que buscará cada carácter "@" y lo reemplazará con sí mismo + "\ n" (que es una "nueva línea" también conocida como CRLF) que activará cada "@" su propia línea en la secuencia de salida ...

3) Cuando canaliza la salida anterior de SED al comando FIND/n, estará agregando números de línea al principio de cada línea. Ahora, todo lo que tiene que hacer es aislar la parte numérica de cada línea y colocar "SET/a" para convertir cada línea en una declaración de lotes que (cada vez más con cada línea) establece la variable igual al número de esa línea.

4) aislar parte numérica de cada línea y prologar el número aislado por lo anterior a través de:
| SED "s/\[\(.*\)\].*/Set \/a NumFound=\1/"

En el fragmento anterior, que está tubería de salida de los comandos anteriores a SED, que utiliza esta sintaxis "s/WhatToLookFor/WhatToReplaceItWith/"para hacer estos pasos:

a) buscar un "["(que debe ser "escapó" por prologando con "\")

b) comenzar a ahorrar (o" tokenización ") lo que sigue, hasta el cierre"] "

--> in other words it ignores the brackets but stores the number 
    --> the ".*" that follows the bracket wildcards whatever follows the "]" 

c) el material entre el \( y la \) es "tokenizados", lo que significa que se puede hacer referencia a más tarde, en la sección "WhatToReplaceItWith". Las primeras cosas que se tokenizan se mencionan a través de "\ 1" y luego como "\ 2", etc.

Entonces ... estamos ignorando [y] y estamos guardando el número que se encuentra entre los corchetes e IGNORANDO todo el resto salvaje de cada línea ... así estamos reemplazando la línea con la cadena literal: Set /a NumFound= + el número guardado, "tokenizado", es decir, ... la primera línea leerá : Set /a NumFound=1 ... & lee la siguiente línea: Set /a NumFound=2 etc etc

Por lo tanto, si usted tiene 1.283 direcciones de correo electrónico, sus resultados tendrán 1.283 líneas.

El último ejecutado = el que importa.

Si utiliza el carácter ">" para redireccionar toda la salida anterior a un archivo por lotes, es decir: > CountChars.bat

... luego simplemente llamar a ese archivo por lotes & tendrá una variable de entorno DOS llamado "NumFound" con su respuesta.

Cuestiones relacionadas