2012-02-16 16 views

risposta

11

Utilizzando quello che hai, si potrebbe pipe i risultati attraverso un find. Ho visto qualcosa di simile usato di tanto in tanto.

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

Così si contano le linee che derivi dalla comando findstr che non hanno la stringa spazzatura in esso. Una specie di trucco, ma potrebbe funzionare per te. In alternativa, usa lo find /c sulla stringa che ti interessa essere lì. Infine, hai citato un indirizzo per riga, quindi in questo caso funziona sopra, ma più indirizzi per riga e questo si interrompe.

+0

Restituisce 1 pure. – Patryk

+0

@Patryk, errore mio, ho letto male che tutte le email erano su ciascuna sulla propria linea. Revisionerà. –

0

L'ho trovato in rete. Vedere se funziona:

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

Grazie per questo, ma 'findstr/R/N" ^. * @. * $ "Mail.txt | find/c "@" restituisce 1 per me. Forse è un problema con i risultati in una sola riga. – Patryk

1

vorrei installare gli strumenti unix sul vostro sistema (a portata di mano in ogni caso :-), allora è molto semplice - guardare per esempio qui:

Count the number of occurrences of a string using sed?

(Usando awk:

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

).

è possibile ottenere gli strumenti di Windows UNIX qui:

http://unxutils.sourceforge.net/

+0

Solo 'grep -c -o @' sarebbe sufficiente (o 'grep -o @ | wc -l' se hai un buggy' grep' che non DTRT). – tripleee

+0

Anche lo script 'awk' conta le righe con occorrenze, non ricorrenze reali. Non è difficile da risolvere, ma è ancora più facile usare 'grep -o'. – tripleee

+0

@ tripleee So che posso usare gli strumenti unix (che è molto più facile da usare) ma mi piacerebbe farlo con la riga di comando di Windows. – Patryk

0

Questo è come lo faccio, utilizzando una condizione AND con FINDSTR (per contare il numero di errori in un file di log):

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: Conta "numero di righe che contengono una corrispondenza di stringa" anziché "numero di occorrenze totali nel file".

3

Potrebbe essere un po 'in ritardo, ma il seguente script ha funzionato per me (il file di origine conteneva i caratteri di citazione, questo è il motivo per cui ho usato il parametro' usebackq '). Il segno di omissione (^) funge da carattere di escape nel linguaggio di script batch di 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

Confermato che ciò funzioni –

1

soluzione molto semplice:

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

ricordare un punto alla fine della linea!

Ecco po 'modo più comprensibile:

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

Prima grep seleziona solo "@" stringhe e mettere ciascuno su nuova linea.

Il secondo grep conta le linee (o le linee con @).

L'utilità grep può essere installata da GnuWin project o da WinGrep siti. È un filtro di testo molto piccolo e sicuro. Grep è uno dei comandi Unix/Linux più utili e io lo uso quotidianamente sia su Linux che su Windows. Il findag per Windows è buono, ma non dispone di tali funzionalità come grep.

L'installazione di grep in Windows sarà una delle migliori decisioni se ti piace la CLI o gli script batch.

2

Perché non semplicemente usando questo (questo determina il numero di linee contenenti (almeno) un @ char.): Uscita

find /C "@" "mail.txt" 

Esempio:

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

Per evitare il nome del file nell'output, sostituirlo con:

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

Esempio:

96 

Per acquisire il numero risultante e memorizzare in una variabile, utilizzare questo (cambiamento %N a %%N in un file batch):

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

Utilizzare questo :

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

Sebbene questo snippet di codice possa risolvere la domanda, [compresa una spiegazione] (http://meta.stackexchange.com/questions/114762/explaining-intlely-based-answers) aiuta davvero a migliorare la qualità del tuo post. Ricorda che stai rispondendo alla domanda per i lettori in futuro, e quelle persone potrebbero non conoscere i motivi del tuo suggerimento sul codice. –

1

OK - così tardi per la tavola, ma ... sembra che molti intervistati perso la specifica originale che tutti gli indirizzi email si verificano su 1 linea. Ciò significa che, a meno che non si introduca un CRLF con ogni occorrenza del simbolo @, i suggerimenti per l'uso delle varianti di FINDSTR/c non saranno di aiuto.

Tra gli strumenti Unix per DOS è il potente SED.exe. Google it. Roccia RegEx. Ecco un suggerimento:

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

Spiegazione: (supponendo che il file con i dati si chiama "Datafile.txt") 1) Il 1 Trovi comprende 3 righe di informazioni di intestazione, che getta un approccio line-count, quindi inserisci i risultati in una seconda (identica) ricerca per eliminare le informazioni di intestazione indesiderate.

2) Conduci i risultati sopra indicati a SED, che cercherà ogni carattere "@" e lo sostituirà con se stesso + "\ n" (che è una "nuova riga" o anche un CRLF) che ottiene ogni "@" su la propria linea nel flusso di output ...

3) Quando si collega l'output precedente da SED al comando FIND/n, si aggiungeranno i numeri di riga all'inizio di ogni riga. Ora, tutto ciò che dovete fare è isolare la porzione numerica di ogni riga e pre-impostarla con "SET/a" per convertire ogni riga in un'istruzione batch che (sempre più con ogni riga) imposta la variabile uguale al numero di quella riga.

4) isolare parte numerica di ogni linea e precedere il numero isolato a quanto sopra attraverso:
| SED "s/\[\(.*\)\].*/Set \/a NumFound=\1/"

Nel frammento di sopra, sei tubazioni in uscita del precedente comandi per SED, che utilizza questa sintassi "s/WhatToLookFor/WhatToReplaceItWith/"per fare questi passi:

a) cercare un "["(che deve essere "sfuggito" di precedere con "\")

b) iniziare a salvare (o" tokenizing ") che segue, fino alla chiusura"] "

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

c) la roba tra il \( e \) è "token", che significa che può essere riferito a seguito, nella sezione "WhatToReplaceItWith". La prima roba che viene tokenizzata si riferisce a "\ 1" quindi seconda a "\ 2", ecc.

Quindi ... stiamo ignorando [e il] e stiamo salvando il numero che si trova tra le parentesi e IGNORING tutto il resto wild-carded di ogni linea ... quindi stiamo sostituendo la linea con la stringa letterale: Set /a NumFound= + il numero salvato, o "tokenized", vale a dire ... la prima riga leggerà : Set /a NumFound=1 ... & riga successiva si legge: Set /a NumFound=2 etc. etc.

Quindi, se si dispone di 1.283 indirizzi di posta elettronica, i risultati avranno 1.283 linee.

L'ultimo eseguito = quello che conta.

Se si utilizza il carattere ">" per reindirizzare tutto l'output sopra per un file batch, vale a dire: > CountChars.bat

... poi basta chiamare che file batch & avrete una variabile di ambiente DOS chiamato "NumFound" con la tua risposta.

Problemi correlati