Basic Anzahl der Funde mit findstr pro Datei ausgeben

Mirumoto

Cadet 1st Year
Registriert
März 2011
Beiträge
11
Hallo zusammen,
ich habe einige txt Dateien, in einigen steht fast nur Text, in anderen hauptsächlich nur Zahlen.
Die Dateien mit den Zahlen würde ich gerne aussortieren, also löschen.

Meine Idee war, dass ich in allen Datein nach einer bestimmten Zahl suche, da ich nicht herausgefunden habe wie man ein Dokument nur nach Zahlen durchsucht, und wenn in einer Datei mehr als 10 Funde sind, lasse ich die Datei löschen.
Allerdings klappt das bei mir nicht..

Mein Ansatz:
Code:
rem @echo off
set anzahl=0
pushd "%UserProfile%\Downloads\"
for /f "tokens=1,2* delims=:" %%i in ('findstr /n /c:"5" "*.txt"') do (
 
echo in Zeile: %%j
echo der Datei: "%%~fi"
echo %anzahl%
pause
Call :count

)

:count
Set /a anzahl=%anzahl%+1
pause

Allerdings zählt "anzahl" ja jetzt die Funde für alle Dateien, so dass ich nicht auf die Funde pro Datei komme..

Freue mich sehr über jede Hilfestellung!!!
Gruß Alex
 
Für das was Du erreichen willst, kommt mir dein Ansatz etwas 'übersichtlich' vor. *g
Bei mir kommt da etwa sowas aus:

Code:
@echo off & setlocal enabledelayedexpansion

set anzahl=0
pushd "%UserProfile%\Downloads\"
for /f "delims=" %%i in ('dir /b *.txt') do (
for /f "delims= " %%h in ('type "%%i"') do (
for %%j in (1,2,3,4,5,6,7,8,9,0) do echo %%h | find "%%j" > nul && set /a anzahl+=1
if !anzahl! GEQ 10 del "%%i" & echo 10 zahlen gefunden, Datei %%i entfernt! & goto done
))

:done
if %anzahl% LSS 10 echo Nichts geloescht!
pause

Wenn allerdings in einer Reihe bspw. 1847565895 steht, wird das nur einen Count geben. 123212 1212313 wären zwei Counts. Ich weiß jetzt nicht, ob oder wie man in der Schleife jedes Zeichen als Trennzeichen werten kann.
 
Zuletzt bearbeitet:
Danke! Das hilft mir schon sehr weiter!

Für mein Verständnis:
Code:
for /f "delims=" %%i in ('dir /b *.txt') do (
= Für jede Datei, richtig? Hier hab ich noch ein set anzahl=0 eingefügt, weil er nach jeder Datei neue zu zählen anfangen soll

Code:
for /f "delims= " %%h in ('type "%%i"') do (
=für jede Zeile?! in der Datei?

Code:
for %%j in (1,2,3,4,5,6,7,8,9,0) do echo %%h | find "%%j" > nul && set /a anzahl+=1
= für jede Zahl die er in der Zeile findet, bzw. wenn er in der Zeile eine Zahl findet, setzt er anzahl +1.

Ich hab das für mich erstmal so umgeschrieben, dass ich eine Ausgabe erhalte, in der lediglich aufgelistet wird, wie viele Zeichen in jeder Datei sind:

Code:
@echo on & setlocal enabledelayedexpansion
     
set anzahl=0
pushd "%UserProfile%\Downloads\"
for /f "delims=" %%i in ('dir /b *.txt') do (
rem set anzahl=0
for /f "delims= " %%h in ('type "%%i"') do (
for %%j in (1,2,3,4,5,6,7,8,9,0) do echo %%h | find "%%j" > nul && set /a anzahl+=1 >nul 
    )
echo !anzahl! Zeichen im Text der Datei  %%i>> %UserProfile%\Downloads\Ausgabe.txt
set anzahl=0
)
Leider funktioniert das set anzahl=0 noch nicht wirklich, hast Du dafür vlt. noch eine Lösung?
Und extrem schick wäre es auch, wenn die Suche nicht nach dem ersten Treffer in der Zeile abgebrochen wird, sondern das weiter gezählt wird.. geht das?

Danke mal wieder!!!
Ergänzung ()

Sorry! Das mit der Anzahl hat sich erledigt, bliebe also nur noch die Suche nach mehreren Stellen in einer Zeile...
 
Das liegt am Leerzeichen bei Delims der zweiten Schleife, mach das mal weg, dann sollte er genau pro zeile zählen. Jedes einzelne Zeichen zu überprüfen wird schwierig und sehr rechenintesinv. Wüsste jetzt nicht wie man das angemessen lösen kann. Du müsstest der Schleife sagen dass jedes Zeichen ein neues token ist, was wiederum andere Probleme mit sich bringt, wenn das gehen würde. Ich befürchte da wirst Du dich auf Fund pro Line beschränken müssen.
 
Mirumoto schrieb:
... bliebe also nur noch die Suche nach mehreren Stellen in einer Zeile...

Das geht auch, ist aber etwas aufwendiger und dauert entsprechend auch etwas länger in der Ausführung.

Hier eine Lösung, die Ziffern, Groß- und Klein-Buchstaben (je a-z), Leerzeichen und sonstige Zeichen zählt:
(Wenn Du wirklich nur die Ziffern brauchst, kannst Du das Beispiel entsprechend kürzen.)

:cool_alt:
Code:
@echo off
cls
setlocal enabledelayedexpansion

for /f %%a in ('dir /b *.txt') do (

    set /a numbers=0
    set /a lcLetters=0
    set /a ucLetters=0
    set /a spaces=0
    set /a other=0
    for /f %%i in ('"type %%a | find /v /c """') do (
        rem ist die letzte Zeile eine Leerzeile,
        rem wird diese (leider) nicht mitgezählt
        set /a linecount=%%i
    )

    for /f "delims=" %%b in (%%a) do (
        set line=%%b
        call :countChars
    )

    echo Datei:        %%~fa
    echo Ziffern:    !numbers!
    set /a letters=!lcLetters!+!ucLetters!
    echo Buchstaben:    !letters!
    echo  davon klein:    !lcLetters!
    echo  und groá:    !ucLetters!
    echo Leerzeichen:    !spaces!
    echo Zeilen:        !linecount!
    echo andere Zeichen:    !other!
    echo.
    set /a total=!numbers!+!letters!+!spaces!+!other!+!linecount!
    echo in Summe:    !total! Zeichen
    echo -------------------------------------------------------
    echo.
)

goto end


:countChars

    rem im Loop wird jede Zeile (%line%) rückwärts Zeichen für Zeichen durchlaufen
    :loop
    if "%line%"=="" goto end
        
        rem in reguläre Ausdrücke (z.B. [0-9] oder [a-z] 
        rem fallen bei findstr leider auch diverse Sonderzeichen
        rem daher als Ausweichlösung z.B. [0123456789]
        
        rem das * ist ein Dummy, um Probleme mit Leerzeichen zu verhindern
        rem würde man nach * suchen, nimmt man für diese Suche ein andere Dummy-Zeichen
        echo %line:~-1%* | findstr /r /c:"[0123456789]" >nul
        if !errorlevel!==0 (
            set /a numbers=%numbers%+1
        ) else (
            echo %line:~-1%* | findstr /r /c:"[abcdefghijklmnopqrstuvwxyz]" >nul
            if !errorlevel!==0 (
                set /a lcLetters=%lcLetters%+1
            ) else (
                echo %line:~-1%* | findstr /r /c:"[ABCDEFGHIJKLMNOPQRSTUVWXYZ]" >nul
                if !errorlevel!==0 (
                    set /a ucLetters=%ucLetters%+1
                ) else (
                    echo %line:~-1%* | findstr /c:" *" >nul
                    if !errorlevel!==0 (
                        set /a spaces=%spaces%+1
                    ) else (
                        set /a other=%other%+1
                    )
                )
            )
        )
    
        set line=%line:~0,-1%
    goto loop
    
goto end


@echo off
:end

Nach dem gleichen Prinzip lässt sich die If-Else-Kette auch erweitern, um z.B. nach diversen Klammern zu suchen.
Da in der Eingabeaufforderung aber ein anderer Zeichensatz genutzt wird, ist die Suche nach einigen "speziellen" Zeichen wie z.B. Umlauten oder ß problematisch.
 
Man Jungs, da bekommt man ja Augenkrebs^^
Bist du dir sicher, dass es unbedingt Batch sein muss?

Nur mal zum Vergleich das ganze in Python
Code:
import glob
import re
import os

for file in glob.glob("*.txt"):
	count = len(re.findall("[0-9]+", open(file).read()))
	if (count > 5):
		print "rm", file, "(", count, ")" 
		os.remove(file)
	else:
		print "keep", file, "(", count, ")"

Das ganze kann man auf drei Codezeilen runterbrechen wenn man die Ausgaben und damit "count" weglässt (und die imports nicht mitzählt^^) und hat damit nicht nur das Zählen, sondern auch schon das Löschen der entsprechenden Dateien. Da ist die Zeit die zum Installieren von Python drauf geht in meinen Augen wesentlich besser angelegt, als das Kämpfen mit so einem Batch-Monster
just my 2ct
 
Na Python kenn ich bisher wirklich nur aus dem Tierreich..

Das Leerzeichen nach dem zweiten Delims hatte ich auch schon entfernt, leifert aber wie gesagt auch nur einen eintrag pro Zeile.

Das könnte mir aber sogar schon reichen, die Rechenzeit ist dabei wirkleich kein zu vernachlässigendes Element..
Und wenn nicht kann ich ja mit dem Code von HDScratcher weitermachen!

Vielen Dank Euch!!!
 
Zurück
Oben