elcheffe123
Goto Top

Batchdatei: Dateien nach String durchsuchen, Dateinamen in .txt speichern

Ahoi!

Der Titel sagt eigentlich schon alles. Ich möchte eine Batchdatei schreiben, die im aktuellen Ordner( unbekannte anzahl an xml`s) den String "blabla" sucht, und, wenn vorhanden, den Dateinamen im gleichen Ordner in die blabla.txt speichert.

Ich dachte eigentlich, dass das per Findstr funktioniert, bei mir tuts das aber nicht. Kann mir da jemand auf die Sprünge helfen?


Grüße

face-smile

Content-ID: 249957

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

Ausgedruckt am: 14.11.2024 um 23:11 Uhr

Friemler
Friemler 23.09.2014 aktualisiert um 23:49:09 Uhr
Goto Top
Hallo,

es könnte sein, dass Deine XML-Dateien in UTF-16 codiert sind, damit kann FINDSTR nicht umgehen - aber TYPE, das kann diese Dateien in die Codepage 850 konvertieren, mit der Konsolenprogramme meistens arbeiten!

Teste mal folgendes:
type "Datei" | findstr /c:"Begriff"

Wenn das auch nicht geht, sind die XML-Dateien evtl. mit UTF-8 oder ANSI codiert (das ist z.B. bei deutschen Umlauten wichtig), dann kann TYPE auch nicht helfen und Du müsstest z.B. auf VBScript ausweichen.

Gruß
Friemler
MK82LST
MK82LST 23.09.2014 um 23:44:55 Uhr
Goto Top
Hallo,

Der String soll im Dateinamen gesucht werden oder im Inhalt der XML-Datei?

Gruß
elcheffe123
elcheffe123 24.09.2014 um 08:35:29 Uhr
Goto Top
Hey,

es soll der Inhalt durchsucht werden!
elcheffe123
elcheffe123 24.09.2014 um 09:50:06 Uhr
Goto Top
Hey!
Mit
type "ordnerpfad/*.xml" | findstr /c:"blabla"
schmeißt er mir jedoch jetzt ALLE dokumente des Ordners raus. Leider bin ich auch zu doof, diese wenigstens alle in einer txt zu speichern... Weiß da jemand einfache Abhilfe?

Grüße
Friemler
Friemler 24.09.2014 um 10:10:29 Uhr
Goto Top
Moin!

Der Schnipsel war eigentlich erstmal nur als Test mit einer Datei gedacht, um herauszufinden, ob FINDSTR überhaupt das geeignete Programm für Deine Aufgabe ist. Aber OK, hier eine etwas erweiterte Version des Schnipsels:

@echo off & setlocal

(for %%f in ("ordnerpfad\*.xml") do (  
   type "%%~f" | findstr /c:"blabla" > NUL && (  
     echo %%~f
   )
)) > "Protokoll.txt"  

Gruß
Friemler
elcheffe123
elcheffe123 24.09.2014 um 11:05:47 Uhr
Goto Top
Hey Friemler,

im Test mit nur einer Datei hat das auch funktioniert. Umsetzen auf den Ordner ergabe dann aber das beschrieben Programm.

Der Codeschnippsel spricht sich für mich IT-Deppen schon wieder wie in ganzes Programm. Mir fehlt leider der Zusammenhang zu dem %%f bzw %%~f. Auch google half mir dabei nicht weiter, daher würde ich dich gerne nochmal quälen;)
Friemler
Friemler 24.09.2014 aktualisiert um 12:13:46 Uhr
Goto Top
Zitat von @elcheffe123:

Mir fehlt leider der Zusammenhang zu dem %%f bzw %%~f.

Hmm, mir fehlt hier auch gerade der Zusammenhang. face-wink Worin besteht das Problem mit meinem zweiten Schnipsel?
elcheffe123
elcheffe123 24.09.2014 um 12:46:05 Uhr
Goto Top
Das war ja auch super Deutsch von mir, wenn ich mir das so nachträglich durchlese. Da fehlt mir selber auch der Zusammenhang in meinem Posting face-wink

Klartext: Dein Code-Schnippsel ist nur ein Schnippsel. Wenn ich den so komplettiere, wie ich meine( Ordnerpfad und Suchabfrage), dann funktioniert es nicht. Die Ausgabedatei bleibt leer. Mir ist schleierhaft, was da noch fehlt.

Vielleicht sollte ich meine uralten Informatik Skripte aus dem Grundstudium nochmal rauskramen- oder auch nicht
elcheffe123
elcheffe123 24.09.2014 um 13:04:54 Uhr
Goto Top
Mit type "Pfad/*.xml" | findstr /M /C:"blabla" >failed.txt
in der cmd-box funktioniert die suche an sich scheinbar, er gibt mir trotz /M bei findstr immer den Text in der Zeile an. Folge ich der Hilfe für findstr sollte das /M doch die reine Ausgabe des Dateinamens bedingen!?
Friemler
Lösung Friemler 24.09.2014, aktualisiert am 25.09.2014 um 10:05:23 Uhr
Goto Top
Zunächst mal etwas allgemeines:

  1. Bitte benutze für die Angabe von Code und/oder Daten die Codeformatierung. Dadurch hebt sich das vom reinen Text in einem Posting optisch besser ab und zusätzlich werden beim Generieren des HTML-Codes der Seite keine Zeichen verschluckt oder verändert. Gerade letzteres führt immer wieder zu Problemen bei der Übernahme von Code bzw. beim Auswerten von Daten durch einen Helfer.
  2. Code, der in einer Codebox (blau-weiß gestreiftes Feld) zur Verfügung gestellt wird, sollte immer durch Klick auf das Wörtchen "Quelltext" in der rechten oberen Ecke der Box und anschließendes Kopieren aus dem dann erscheinenden Fenster übernommen werden. Niemals den Code abtippen oder direkt aus der Codebox heraus kopieren.

Jetzt zu Deinem Schnipsel:
type "Pfad/*.xml" | findstr /M /C:"blabla" >failed.txt 
  1. Wenn man TYPE mit Wildcards (hier das *-Zeichen) startet, gibt der Befehl eine kontinuierliche Folge von Zeilen aus, indem alle Dateien, auf die das Namensmuster passt, nacheinander ausgegeben werden. Vor den Zeilen einer Datei wird immer der Dateiname und eine Leerzeile ausgegeben. Sollte der Dateiname auf das Suchmuster von FINDSTR passen, wird die Zeile mit dem Dateinamen als Treffer gewertet. Deshalb ist der Aufruf von TYPE mit Wildcards für Dein Problem ungeeignet.
  2. Da FINDSTR vom TYPE-Befehl nur einen ASCII-Stream als Eingabe bekommt und nichts von den verschiedenen Dateien weiß, die TYPE als passend auf das Namensmuster erachtet, hat der Parameter /M für FINDSTR keinen Nutzen - der ASCII-Stream wird als eine Datei betrachtet. Der Parameter /M hat nur Sinn, wenn FINDSTR selbst die zu durchsuchenden Dateien auswählt, da es ja dann weiß, in welcher Datei ein Treffer gefunden wurde. Da FINDSTR aber nicht mit UTF-16 codierten Dateien umgehen kann und deshalb TYPE für die Konvertierung benötigt wird, ist dieser Weg für Dein Problem ungeeignet.

Ich poste hier nochmal eine etwas änderungsfreundlichere Version meines zweiten Scripts, evtl. hast Du bei Deinen Anpassungen versehentlich ein syntaktisch wichtiges Zeichen gelöscht.
@echo off & setlocal

set "SrcDir=Pfad"  
set "FileType=xml"  
set "SearchKey=blabla"  
set "LogFile=Protokoll.log"  

(for %%f in ("%SrcDir%\*.%FileType%") do (  
   type "%%~f" | findstr /c:"%SearchKey%" > NUL && (  
     echo %%~f
   )
)) > "%LogFile%"  

Gruß
Friemler
elcheffe123
elcheffe123 25.09.2014 aktualisiert um 10:09:04 Uhr
Goto Top
Super Ding, das funktioniert. Vielen Dank!
Danke auch für deine Hinweise, ich habe verzweifelt die "Zitierfunktion" gesucht ;)

Dein Code gibt mir nun den kompletten Pfad aus, wie komme ich nun an den reinen Dateinamen, ohne Endung. Versucht hab ich es mit einem
  type "%%~fn" | findstr /c:"%SearchKey%" > NUL && (  
     echo %%~fn
, allerdings behauptet er dann, das file nicht zu finden. Ist das vielleicht nur ein Syntaxfehler?

Grüße

face-smile
Friemler
Lösung Friemler 26.09.2014 aktualisiert um 11:14:53 Uhr
Goto Top
Zitat von @elcheffe123:

Ist das vielleicht nur ein Syntaxfehler?

Nee, ist ein semantischer und zusätzlich auch ein Denkfehler. face-wink

Zunächst mal müsste es richtigerweise %%~nf heißen, da %%f die Laufvariable der FOR-Schleife ist, man mit ~ mitteilt, dass umschließende Anführungszeichen entfernt werden sollen und mit n ausdrückt, dass aus der in %%f enthaltenen Pfadangabe der Dateiname extrahiert werden soll. Aber ich denke, da hast Du Dich in Deinem Posting schlicht verschrieben, sonst hättest Du einen anderen Fehler erhalten. Es wäre nämlich versucht worden, den Inhalt der FOR-Laufvariablen n (die nicht existiert) zu einem vollständigen Dateipfad zu erweitern.

Weiterhin ist beim ECHO-Befehl das %%~nf genau richtig, beim TYPE-Befehl führt es zum von Dir genannten Fehler (TYPE benötigt eben einen vollständigen Pfad, wenn das Script nicht zufälligerweise im gleichen Verzeichnis wie die zu verarbeitenden Dateien gespeichert wurde). Bei TYPE also nur %%~f schreiben (aber wie bisher in Anführungszeichen eingeschlossen!), dann klappt's auch mit dem Script-Code.

Gruß
Friemler
elcheffe123
elcheffe123 26.09.2014 um 11:31:22 Uhr
Goto Top
Hey Friemler,
ob du's glaubst oder nicht, dieser Fehler ist mir gestern noch selber aufgefallen und das Skript funktioniert(e) sehr gut. Danke hierfürface-smile

Ist es nun per Batch auch möglich in der For schleife 2 Bedingungen einzufügen? Also:
Suche am Anfang der Zeile nach "Blabla" und am Ende der Zeile nach "bloblo"? Oder gibt es die möglichkeit den string so zu definieren, dass nur das Ende und der Anfang fix sind? "blabla * bloblo"
Leider hab ich zwischen den relevanten Begriffen nun eine generische, immer veränderliche ID.
Friemler
Friemler 26.09.2014 aktualisiert um 14:52:50 Uhr
Goto Top
Hi,

tjaaaa, jetzt kommen wir wieder ein Stückchen näher an die Grenze, ab der Batchscript für Deine Aufgabe nicht mehr brauchbar ist, denn die Implementierung von regulären Ausdrücken durch FINDSTR ist zum einen sehr rudimentär und zum anderen nicht fehlerfrei.

Aber noch kommen wir klar. Teste mal
@echo off & setlocal

set "SrcDir=Pfad"  
set "FileType=xml"  
set "SearchKey1=blabla"  
set "SearchKey2=bloblo"  
set "LogFile=Protokoll.log"  

(for %%f in ("%SrcDir%\*.%FileType%") do (  
   type "%%~f" | findstr /r /c:"^%SearchKey1%.*%SearchKey2%$" > NUL && (  
     echo %%~nf
   )
)) > "%LogFile%"  

Wenn die beiden Suchbegriffe nur gefunden werden sollen, wenn sie auf einer Wortgrenze liegen, ersetze Zeile 10 durch
type "%%~f" | findstr /r /c:"^%SearchKey1% .* %SearchKey2%$" > NUL && ( 

Gruß
Friemler


[EDIT]

WICHTIG!! Falls Zeichen wie *.^$ in Deinem Suchmuster vorkommen, musst Du sie durch ein vorangestelltes \ "escapen", damit sie von FIINDSTR nicht als Bestandteil eines regulären Ausdrucks interpretiert werden. Wenn es Schwierigkeiten gibt, musst Du auf jeden Fall das Suchmuster in Deinem Posting angeben und auch einen repräsentativen Ausschnitt der Daten, die durchsucht werden sollen

[/EDIT]
ITACKER
ITACKER 21.04.2017 um 10:50:44 Uhr
Goto Top
Hallo,

auch wenn der Eintrag etwas älter ist. Ich hoffe, er wird noch gelesen.
Wie kann ich einen String suchen (in einem Batch-Skript) wenn dieser ein % enthält?

Ich möchte 100% in einer Datei suchen, folgender Code funktioniert leider nicht:

findstr /C:"100\%" %FTP_LOG%

Ich habe auch andere Versionen ausprobiert, wie
findstr /C:"100%" %FTP_LOG%


Danke schon mal für die Unterstützung

Gruß
Irma
Friemler
Friemler 21.04.2017 um 14:46:10 Uhr
Goto Top
Hallo Irma,

folgendes sollte funktionieren:
findstr /c:"100%%" "%FTP_LOG%"

In Batchscript werden literale %-Zeichen durch Verdopplung "escaped".

Grüße
Friemler
ITACKER
ITACKER 21.04.2017 um 16:31:03 Uhr
Goto Top
Super, vielen Dank. Das hat funktioniert.

Grüße
Irma
Retkar
Retkar 08.05.2017 um 11:55:28 Uhr
Goto Top
Hey Friemler,

vielleicht kannst du ja auch mir weiter helfen.
Also ich würde gerne ein Verzeichnis welches nur mit Log Files befühlt ist durchsuchen. Und zwar sollte das Skript alle Log Files nach dem String "ERROR" durchsuchen und mir in eine txt oder ein Log File die Auflisten welche diesen String enthalten.

@echo off & setlocal 
(for %%f in ("F:\...\*.log") do ( 
type "%%~f" | findstr /"ERROR" > NUL && ( 
echo %%~f 

)) > "Protokoll.txt"

habe ich versucht zu nutzen, jedoch werden mir dann einfach alle Logs in die txt geschrieben mit und ohne Error. mit dem Befehl der ausgeführt wurde.
Würde es irgenwie funktionieren das in dem Protokoll.txt nur die Log´s enthalten sind die tatsächlich einen ERROR enthalten?

MfG
Ratker
132895
132895 08.05.2017 aktualisiert um 12:02:56 Uhr
Goto Top
@Retkar
Da reicht ein
findstr /ic:"ERROR" "F:\Ordner\*.log" >"Protokoll.txt"  
oder wenn nur die Dateinamen rein sollen:
>"Protokoll.txt" (for /f "tokens=1 delims=:" %%a in ('findstr /ic:"ERROR" "F:\Ordner\*.log"') do echo(%%a)  
Gruß
Retkar
Retkar 08.05.2017 um 12:27:17 Uhr
Goto Top
Vielen lieben Dank Password,

damit wäre der Anfang getan. Wäre es jetzt auch möglich die Logs per Anhang an eine mail zu schreiben und im besten Fall den Inhalt von Protokoll.txt als Inhalt der Mail zu verschicken ?

mein Ansatz momentan:
"F:\..\sas.exe" -Batch -noterminal -logparm "x=y" -sysin "F:\...\mailsenden.sas" set betreff "Betreff" -set email "email@gmx.de" -set text "Error" -set anhang "F:\..\xy.log"

"ERROR"= Hier sollten die Fehlermeldungen stehen
"anhängen" = Hier sollten die Fehler Logs angehängt sein

mit diesem Befehl bekomme ich momentan schon mal eine mail zugeschickt mit dem Inhalt "ERROR" und einem Log das ich aber Festlegen muss

könnte man dies abändern um Wirklich nur die Logs mit einem Fehler zu bekommen. Also das diese Angehängt werden und der Text der Mail Die Protokoll.txt ist ?

Grüße
Ratkar
132895
132895 08.05.2017 aktualisiert um 12:37:10 Uhr
Goto Top
Mail versenden, einfach die Suchfunktion bemühen:

PS
$path = 'F:\Ordner\*.log'  
$files = select-string -Pattern 'ERROR' -SimpleMatch -Path $path -List | select -Expand Filename  
if ($files){
    Send-MailMessage -From "user@domain.de" -to "empfaenger@domain.de" -Subject "Dienst läuft nicht" -SmtpServer smtp.domain.de -Credential (New-Object PSCredential("USERNAME",(ConvertTo-SecureString 'PASSWORD' -AsPlainText -Force))) -UseSSL -Attachments $files  
}else{
     write-host "Keine Logs mit 'ERROR' gefunden"  
}
Retkar
Retkar 08.05.2017 um 14:22:54 Uhr
Goto Top
Danke Password,

jedoch klappt dies nicht ganz wie es soll, ich versuche Gerade noch mit den Schnipseln an meinem Code zu basteln
"F:\..\sas.exe" -Batch -noterminal -logparm "x=y" -sysin "F:\...\mailsenden.sas" set betreff "Betreff" -set email "email@gmx.de" -set text "Error" -set anhang "F:\..\xy.log"  
so bekomme ich eine Mail aber nur mit dem Text ERROR und dem Log File das ich auch angebe

dachte an etwas wie :
$path = 'F:\Ordner\*.log'   
$files = select-string -Pattern 'ERROR' -SimpleMatch -Path $path -List | select -Expand Filename   
F:\..\sas.exe" -Batch -noterminal -logparm "x=y" -sysin "F:\...\mailsenden.sas" set betreff "Betreff" -set email "email@gmx.de" -set text "Error" -set -Attachments $files   
damit der Anhang mit dem Pattern ERROR angehängt wird. So bekomme ich Jedoch gar keine Mail mehr.

MfG
Sarumahr
Sarumahr 17.07.2019 um 13:08:09 Uhr
Goto Top
Problem dabei ist nur das der String "blabla" auch gefunden wird wenn man nach "blabl" suchen lässt. Kann man dies irgendwie vermeiden?
ChuckyaliasJ154
ChuckyaliasJ154 03.07.2022 um 14:51:42 Uhr
Goto Top
Hallo!

Ich habe bei dem Ursprungsscript noch eine Frage. Wie muss es angepasst werden, wenn ich anstatt des Dateinamen, die stelle zwischen den Suchbegriffen in eine Log schrieben will?

Ich würde gern in einem Ordner alle (Taxtbasierten) Dokumente nach einem fest definierten String durchsuchen.
Dieser beginnt immer mit <START TEST="Resultat"> und endet mit </ENDE>

Also sozusagen so: <START TEXT="Resultat">HIER STEHT DAS RESULTAT</ENDE>

Ich würde gern aus den immer unterschiedlich vorhandenen Dateien den Bereich zwischen ...Resultat"> und </ENDE> auslesen und eine Log Datei schreiben. Der Bereich kann länger aber auch kürzer sein. Einzig <START TEXT="Resultat"> und </ENDE> sind immer gleich.

Kann mir jemand bei der Lösung weiter helfen?