rebsnb
Goto Top

Mehrere Texte aus mehreren Dateien raussuchen

Hallo zusammen,

ich kenne mich so gut wie gar nicht mit BATCH-Programmierung aus.
Ich habe folgende Aufgabenstellung:

In einer Textdatei stehen mehrere Suchbegriffe unterschiedlicher Länge ( 1 Suchbegriff pro Zeile )
Nun möchte ich in einem bestimmten Verzeichnis alle Dateien nach allen Suchbegriffen durchsuchen
und in einer neuen Textdatei jeweils den Namen der Datei, die Zeilennummer und Suchtext ausgeben
, wenn dieser darin vorkommt.
Kann mir da jemand helfen?

Vielen Dank im Vorraus.

Content-Key: 153144

Url: https://administrator.de/contentid/153144

Printed on: April 23, 2024 at 09:04 o'clock

Mitglied: 60730
60730 Oct 15, 2010 at 12:28:51 (UTC)
Goto Top
Salü,

wie "groß" ist denn der Umfang?

Denn Batch hat seine Grenzen - sehr wahrscheinlich geht es mit VBS schneller.
(Der Such & Loglauf)

alle Dateien nach allen Suchbegriffen
PDF / Wörd und co kannst mit Batch eh nicht beackern...

Gruß
Member: REBSNB
REBSNB Oct 15, 2010 at 12:34:11 (UTC)
Goto Top
Hallo,
das geht ja schnell hier!
Im Verzeichnis sind etwa 15 Dateien ca. 100kb gross.
Anzahl an Suchbegriffen ca. 5

VBS ginge wohl auch.
Member: Friemler
Friemler Oct 15, 2010 at 12:51:44 (UTC)
Goto Top
Hallo REBSNB,

dazu sollte folgender Code genügen:
@echo off

setlocal

set "SearchExpressions=PfadUndNameDerDateiMitSuchbegriffen"  
set "FolderToScan=DerPfadZumOrdnerMitDenDateien"  
set "LogFile=PfadUndNameDerZieldatei"  

del "%LogFile%" 2>NUL  

for /f "usebackq delims=" %%e in ("%SearchExpressions%") do (  
  >>"%LogFile%" findstr /n /r /c:"\<%%e\>" "%FolderToScan%\*.*"  
  >>"%LogFile%" echo %%e  
  >>"%LogFile%" echo.  
)

endlocal

Zuerst wird eine evtl. vorhandene alte Ausgabedatei gelöscht. Existiert sie nicht, wird die Fehlermeldung durch 2>NUL nicht angezeigt.

Der Suchstring wird (durch /r) als regulärer Ausdruck betrachtet. FINDSTR sucht nach dem Suchstring buchstabengetreu (durch /c:) und an Wortgrenzen, \<=Wortanfang, \>=Wortende. Wenn das nicht Deinen Anforderungen entspricht, diese Zeichen und den Parameter /r entfernen. Die Zeilennummern werden durch /n ausgegeben. Der Suchstring kann auch Leerzeichen enthalten. Die Ausgabedatei ist nach folgendem Schema aufgebaut:
Dateiname:Zeilennummer:Inhalt der Zeile
gesuchter Ausdruck
Leerzeile
:
:

Wenn Du nur reinen Text ohne Sonderzeichen suchst, ist das ausreichend. Wenn nicht, ist VBScript besser.

Gruß
Friemler
Mitglied: 60730
60730 Oct 15, 2010 at 12:59:03 (UTC)
Goto Top
Dann drösel ich das mal auf, auch auf die Gefahr hin, dass einer der beiden B´s bereits batcheln...
Zitat von @REBSNB:
Hallo zusammen,

ich kenne mich so gut wie gar nicht mit BATCH-Programmierung aus.
Ich habe folgende Aufgabenstellung:

In einer Textdatei stehen mehrere Suchbegriffe unterschiedlicher Länge ( 1 Suchbegriff pro Zeile )
ok
Nun möchte ich in einem bestimmten Verzeichnis alle Dateien nach allen Suchbegriffen durchsuchen
das kann findstr
und in einer neuen Textdatei jeweils den Namen der Datei, die Zeilennummer und Suchtext ausgeben
"Zeilennummer" schreit ja gerade nach Findstr /n
, wenn dieser darin vorkommt.
Kann mir da jemand helfen?
sicherlich face-wink

Ein schnellschuss aus der Hüfte:

  • Ich habe viele cmds im Ordner C:\script\
  • dort (C:\script\test.ini) liegt die "steuerdatei"
  • C:\script\test.ini ist ein durchlauferhitzer der bei jedem Treffer neugeschrieben wird
  • C:\script\test2.ini ist das endresultat
  • das ist keine batch, sondern eine Demo für die Dosbox - als batch müssen die einzelnen % gegen %% getauscht werden.

for /f %a in (C:\script\test.txt) do for /f %b in ('dir /s /b c:\script\*.cmd') do (findstr /n "%a" %b>C:\script\test.ini && echo %b %a>>C:\script\test2.ini|type c:\script\test.ini>>C:\script\test2.ini)  

try it

edit der Friemler (zur Abwechslung) face-wink /edit
Member: REBSNB
REBSNB Oct 15, 2010 at 13:12:48 (UTC)
Goto Top
Hallo Friemler,

nach Ausführen der Batch Datei wird eine NULá Datei im Verzeichnis erstellt.
Lösche ich zuvor die "Ergebnisdatei" steht in der NULá Datei "Ergebnisdatei.txt konnte nicht gefunden werden"

Vielleicht nur ein Schreibfehler ???

LG
Norbert
Member: Friemler
Friemler Oct 15, 2010 at 13:20:07 (UTC)
Goto Top
Hallo REBSNB,

poste bitte Deine Batchdatei so wie Du sie ausführst und bitte auch die Suchbegriffe (sind ja nur 5). Dabei bitte die Code-Formatierung benutzen. Das beschriebene Verhalten kann ich mir nicht erklären.

Gruß
Friemler
Member: REBSNB
REBSNB Oct 15, 2010 at 13:28:34 (UTC)
Goto Top
Hallo Friemler

Batch Datei:
@echo off                                                         
                                                                  
setlocal                                                          
                                                                  
set "SearchExpressions=C:\TEST\TEST_FORUM\Suchbegriffe.txt"         
set "FolderToScan=C:\TEST\TEST_FORUM\Dateien"                    
set "LogFile=C:\TEST\TEST_FORUM\Ergebnis.txt"                               
                                                                  
del "%LogFile%" 2>NUL                                               
                                                                  
for /f "usebackq delims=" %%e in ("%SearchExpressions%") do (       
   >>"%LogFile%" findstr /n /r /c:"\<%%e\>" "%FolderToScan%\*.*"    
   >>"%LogFile%" echo %%e                                           
   >>"%LogFile%" echo.                                              
)                                                                 
                                                                  
endlocal 
Suchbegriffe.txt:

01.JPG
02.BMP

Weis leider nicht so genau, was du mit Code-Formatierung meinst.

LG
Norbert

[Edit Biber]
Weis leider nicht so genau, was du mit Code-Formatierung meinst.
Schau dir meine Änderungen in diesem Kommentar an (mit "Editieren" auf diesen Kommentar. [/Edit]
[
Member: REBSNB
REBSNB Oct 15, 2010 at 13:42:00 (UTC)
Goto Top
Hallo Timo:

Ergebnis in Test2:

c:\TEST\TEST_FORUM\Dateien\suchen1.txt 01.JPG
01.JPG
02.BMP


c:\TEST\TEST_FORUM\Dateien\suchen2.txt 01.JPG
01.JPG
02.BMP


c:\TEST\TEST_FORUM\Dateien\suchen1.txt 02.BMP
01.JPG
02.BMP


01.JPG
02.BMP


Die Suchbegriffe werden auch dann angezeigt, wenn sie in den Suchdateien nicht vorkommen. Leider wird die Zeilennummer auch nicht ausgegeben. Hier noch meine Suchdateien:

suchen1.txt:
fhfghgfh12303.JPGasdasd
fghgfhf
trzt02.BMPrz456asasd
erter

Suchen2.txt:
fhfghgfh12301.JPGasdasd
fghgfhf
wer
wer
wer
wer
ipp
trzt02.BMPrz456asasd
erter


Noch ne Idee?

LG
Norbert
Member: Friemler
Friemler Oct 15, 2010 at 13:54:00 (UTC)
Goto Top
Hallo Norbert,

nachdem ich nun den Code auch mal getestet habe (hüstel) konnte ich Deinen Fehler nicht nachvollziehen. Habe aber trotzdem noch eine kleine Verbesserung eingefügt. Jetzt werden die Suchbegriffe (und die Leerzeile) nur noch in die Ergebnisdatei geschrieben, wenn sie vorher auch in einer der zu durchsuchenden Dateien gefunden wurden.

Um Copy 'n Paste-Fehler zu vermeiden, klicke auf das Wort Quelltext rechts oben in der Box mit dem Skript-Code und kopiere den Quelltext aus dem sich dann öffnenden Fenster.

@echo off                                                         
                                                                  
setlocal                                                          
                                                                  
set "SearchExpressions=C:\TEST\TEST_FORUM\Suchbegriffe.txt"         
set "FolderToScan=C:\TEST\TEST_FORUM\Dateien"                    
set "LogFile=C:\TEST\TEST_FORUM\Ergebnis.txt"                               
                                                                  
del "%LogFile%" 2>NUL                                               
                                                                  
for /f "usebackq delims=" %%e in ("%SearchExpressions%") do (       
   >>"%LogFile%" (findstr /n /r /c:"\<%%e\>" "%FolderToScan%\*.*"  && (echo %%e & echo.))  
)                                                                 
                                                                  
endlocal 

Gruß
Friemler
Mitglied: 60730
60730 Oct 15, 2010 at 13:55:42 (UTC)
Goto Top
moinsen (again)

ich hab etwas länger gebraucht, weil ich den einzeiler auch getestet hab.

Nur habe ich eine "steuerdatei" C:\script\test.txt in der die zu suchenden Inhalte stehen.

Oder andersherum:


Rem für jeden Treffer %a in Steuerdatei "mache" für jeden Treffer %b im Verzeichnis und unterverzeichnis c:\script\*.cmd "mache(schreibe)" finde Treffer %a in %b nach C:\script\test.ini im Erfolgsfall (Treffer in Datei gefunden) schreibe %b (Dateinamen mit Pfad) %a (Suchwort) in das Logfile C:\script\test2.ini

for /f %a in (C:\script\test.txt) do for /f %b in ('dir /s /b c:\script\*.cmd') do (findstr /n "%a" %b>C:\script\test.ini && echo %b %a>>C:\script\test2.ini|type c:\script\test.ini>>C:\script\test2.ini)  

Und was hast du?
Member: REBSNB
REBSNB Oct 15, 2010 at 14:11:31 (UTC)
Goto Top
Hallo Timo,

meine "Steuerdatei" heisst Suchbegriffe.txt und sieht folgendermassen aus:

01.JPG
02.BMP

habe gerade festgestellt, dass dein Programm im Grunde genau das richtige macht, wenn ich es in Excel mit sortieren, filtern und doppelten Spalten eliminieren nachbearbeite. Hätte mir folgenden Ausdruck gewünscht:

c:\TEST\TEST_FORUM\Dateien\suchen1.txt
Zeilennummer: 01.JPG
Zeilennummer: 02.BMP

c:\TEST\TEST_FORUM\Dateien\suchen2.txt
Zeilennummer: 01.JPG


LG
Norbert
Member: REBSNB
REBSNB Oct 15, 2010 at 14:14:14 (UTC)
Goto Top
sorry, meinte:


c:\TEST\TEST_FORUM\Dateien\suchen1.txt
Zeilennummer: 02.BMP

c:\TEST\TEST_FORUM\Dateien\suchen2.txt
Zeilennummer: 01.JPG
Zeilennummer: 02.BMP
Member: bastla
bastla Oct 15, 2010 at 14:23:38 (UTC)
Goto Top
Hallo REBSNB und willkommen im Forum!

Ziemlich ähnlicher Ansatz wie bereits von Friemler und T-Mo (wobei Groß-/Kleinschreibung nicht unterschieden wird - falls doch gewünscht, "/i" entfernen):
@echo off & setlocal                                                          

set "SearchExpressions=C:\TEST\TEST_FORUM\Suchbegriffe.txt"  
set "FolderToScan=C:\TEST\TEST_FORUM\Dateien"      
set "LogFile=C:\TEST\TEST_FORUM\Ergebnis.txt"  

type NUL>"%LogFile%"  
for /f "usebackq delims=:" %%e in ("%SearchExpressions%") do for /f "tokens=1-3 delims=:" %%i in ('findstr /i /n /c:"%%e" "%FolderToScan%\*.*"') do (  
    findstr /b /c:"%%i:%%j" "%LogFile%">nul || (  
        echo\
        echo %%i:%%j
    )
    echo %%k: %%e
)>>"%LogFile%"  
Grüße
bastla
Member: Friemler
Friemler Oct 15, 2010 at 15:58:41 (UTC)
Goto Top
Hallo bastla,

tut mir leid das sagen zu müssen, aber Dein Skript liefert falsche Ergebnisse. Der Grund ist folgender:

Beim ersten Durchlauf der äußeren FOR-Schleife wird der erste Suchbegriff ausgewählt. Danach wird in dem Ausdruck 1
findstr /i /n /c:"%%e" "%FolderToScan%\*.*"  
im Kopf der zweiten FOR-Schleife gesucht. Erzeugt wird eine Liste der Dateinamen mit Zeilennummern und Zeileninhalt. Der Ausdruck 2
findstr /b /c:"%%i:%%j" "%LogFile%">nul || (  
    echo\
    echo %%i:%%j
)
prüft, ob der Dateiname schon in der Ergebnisdatei steht, wenn nicht wird er dort hinein geschrieben.

Beim nächsten Durchlauf der äußeren FOR-Schleife (also bei der Suche nach dem nächsten Suchbegriff) liefert Ausdruck 1 wieder eine Dateiliste. Wenn Suchbegriff 1 und Suchbegriff 2 beide in mehreren Dateien vorkommen, tauchen deren Dateinamen sowohl in der Liste, die Ausduck 1 im ersten Durchlauf liefert, als auch in der Liste, die Ausdruck 1 im zweiten Durchlauf liefert, auf. Da der Name der ersten Datei schon in der Ergebnisdatei enthalten ist, schreibt Ausdruck 2 den Namen nicht nochmal hinein. Nur die Zeilennummer und der Suchbegriff landen in der Ergebnisdatei. Dadurch wird der Eindruck erweckt, der zweite Suchbegriff käme nur in der zweiten Datei vor.

Leider habe ich aber auch noch keine funktionierende Alternative (nich' hauen! face-wink ).

Gruß
Friemler
Member: bastla
bastla Oct 15, 2010 at 16:41:43 (UTC)
Goto Top
Hallo Friemler!
tut mir leid das sagen zu müssen, aber Dein Skript liefert falsche Ergebnisse.
Muss Dir nicht leid tun face-smile - war leider das Ergebnis von "Zwischendurch-Batchen" ...

Wenn ja eigentlich jede Datei nur einmal "angefasst" werden darf, müsste das eher so aussehen:
@echo off & setlocal                                                          

set "SearchExpressions=C:\TEST\TEST_FORUM\Suchbegriffe.txt"  
set "FolderToScan=C:\TEST\TEST_FORUM\Dateien"      
set "LogFile=C:\TEST\TEST_FORUM\Ergebnis.txt"  

type NUL>"%LogFile%"  
for %%d in ("%FolderToScan%\*.*") do findstr /i /g:"%SearchExpressions%" "%%d" >nul && (  
    echo\
    echo %%~fd
    for /f "usebackq delims=" %%e in ("%SearchExpressions%") do for /f "delims=:" %%i in ('findstr /i /n /c:"%%e" "%%d"') do echo %%i: %%e  
)>>"%LogFile%"  
Grüße
bastla
Member: Friemler
Friemler Oct 15, 2010 at 16:53:38 (UTC)
Goto Top
Hi bastla,

jepp, jetzt stimmt's. Wollte gerade meine Variante posten, aber Du warst schneller (und kürzer).

Gruß
Friemler
Member: bastla
bastla Oct 15, 2010 at 16:58:21 (UTC)
Goto Top
Hallo Friemler!
Wollte gerade meine Variante posten, aber Du warst schneller (und kürzer).
So what? Kann ja nicht schaden, mehrere Alternativen darzustellen ...

[Edit]
Ich hab' inzwischen auch schon mal an die ziemlich sicher folgende Frage "Lassen sich die Fundstellen denn nicht nach Zeilennummern sortieren?" gedacht:
@echo off & setlocal                                                          

set "SearchExpressions=C:\TEST\TEST_FORUM\Suchbegriffe.txt"  
set "FolderToScan=C:\TEST\TEST_FORUM\Dateien"      
set "LogFile=C:\TEST\TEST_FORUM\Ergebnis.txt"  

set "T4F=%temp%\Temp4File.txt"  
set "Sorted=%temp%\Sorted.txt"  
type nul>"%LogFile%"  
for %%d in ("%FolderToScan%\*.*") do findstr /i /g:"%SearchExpressions%" "%%d" >nul && (  
    echo\
    echo %%~fd
	del "%T4F%" 2>nul  
	for /f "usebackq delims=" %%e in ("%SearchExpressions%") do for /f "delims=:" %%i in ('findstr /i /n /c:"%%e" "%%d"') do call :ProcessLine %%i "%%e"  
	call :SortIt
	type "%T4F%"  
)>>"%LogFile%"  
goto :eof

:ProcessLine
set /a Nr=100000+%1
>>"%T4F%" echo %Nr%:%2  
goto :eof

:SortIt
sort "%T4F%" /o "%Sorted%"  
del "%T4F%"  
for /f "usebackq tokens=1* delims=:" %%a in ("%Sorted%") do set /a Nr=%%a-100000 & call :WriteLine %%b  
goto :eof

:WriteLine
>>"%T4F%" echo %Nr%:%~1  
goto :eof
Wenn mehr über die Suchbegriffe bekannt wäre (insbes., ob diese "!" enthalten), ließe sich das durch Verwendung von "delayedExpansion" natürlich noch etwas hybscher gestalten ...
[/Edit]

Grüße
bastla
Member: Friemler
Friemler Oct 15, 2010 at 17:22:35 (UTC)
Goto Top
Hallo bastla,

Zitat von @bastla:
So what? Kann ja nicht schaden, mehrere Alternativen darzustellen ...

Habe mich die letzten paar Minuten mit unserem Spam-Bot User A14011997 beschäftigt...

OK, here we go
@echo off

setlocal

set "SearchExpressions=C:\TEST\TEST_FORUM\Suchbegriffe.txt"  
set "FolderToScan=C:\TEST\TEST_FORUM\Dateien"  
set "LogFile=C:\TEST\TEST_FORUM\Ergebnis.txt"  

del "%LogFile%" 2>NUL  
pushd "%FolderToScan%"  

for /f "delims=" %%f in ('dir /b /a:-d') do (  
  for /f "usebackq delims=" %%e in ("%SearchExpressions%") do (  
    for /f "delims=:" %%n in ('findstr /n /r /c:"\<%%e\>" "%%f"') do (  
      findstr /b /c:"%%f" "%LogFile%" > NUL || (echo\ & echo %%f)  
      echo %%n: %%e
    )>>"%LogFile%"  
  )
)

popd

endlocal

Ein Konglomerat aus TimoBeil/bastla/Friemler.

[Edit]
Und trotzdem erst durch bastla's Hinweis fehlerfrei (s.u.).

Gruß
Friemler
Member: bastla
bastla Oct 15, 2010 at 17:29:32 (UTC)
Goto Top
Hallo Friemler!
Ein Konglomerat aus TimoBeil/bastla/Friemler
Das hat doch was ... face-wink

Ich würde allerdings die Zeile 10 durch
pushd "%FolderToScan%"  
for /f "delims=" %%f in ('dir /b /a:-d') do (  
ersetzen (und natürlich knapp vor "endlocal " noch "popd" einfügen) ...

Grüße
bastla

P.S.:
Habe mich die letzten paar Minuten mit unserem Spam-Bot User A14011997 beschäftigt...
... habe ich für mich inzwischen schon unter "Zeitverschwendung" abgelegt ...
Member: Friemler
Friemler Oct 15, 2010 at 17:39:42 (UTC)
Goto Top
Hallo bastla,

tja, ja wenn man nicht jedesmal testet...

PS:
Zitat von @bastla:
... habe ich für mich inzwischen schon unter "Zeitverschwendung" abgelegt ...
Aber Bibers Kommentare sind köstlich... face-wink

Gruß
Friemler
Member: REBSNB
REBSNB Oct 18, 2010 at 06:04:29 (UTC)
Goto Top
Guten morgen Ihr Helden,

vielen Dank für das Script. Genau so wollte ich es haben. Mühsame Sucharbeit ist nun Vergangenheit.
DANKE, DANKE, DANKE.

Eine Frage nur noch : Lassen sich die Fundstellen denn nicht nach Zeilennummern sortieren? (sorry, ein bisschen Spaß muss sein)

Im Moment brauche ich es zwar nicht, aber vielleicht könnte man Eure Gemeinschaftsarbeit ja noch weiter verbessern, indem man noch eine
Suchen und Ersetzen Funktion mit implementiert.

LG
Norbert
Mitglied: 60730
60730 Oct 18, 2010, updated at Oct 18, 2012 at 16:43:48 (UTC)
Goto Top
moin,

Suchen und Ersetzen Funktion mit implementiert.

1.) ist das doch ne ganz andere Baustelle - die dann wieder kein späterer potentieller Fragesteller findet
2.) apropos "finden" - da haben die Köche schon mal was

Gruß