lalaman
Goto Top

Mit findstr eine Zeile zurück

Guten Abend allerseits!

Habe ein denk ich mal nicht so aufwändiges Problem...

ich möchte mit findstr eine txt durchsuchen auf ein bestimmtest Muster und wenn dieses in einer Zeile gefunden wurde, die Zeile selbst und die darüber in eine neue txt kopieren.

so in der Richtung müsste es ja aussehen...


for /F "delims= tokens=1" %%a in ('findstr /I "Muster" List.txt') do echo %%a >>Neue_List.txt


Bsp-Text:

asdkuhuwqajshd
asdlkjfhjlkhfa
aösdljMusteras
ösldkjfmnsadlj


...dann würde ich in der neuen txt gerne diese Zeilen haben: "aösdljMusteras" und "asdlkjfhjlkhfa"

hoffe das war einigermaßen verständlich


mfg
lalaman

Content-Key: 95042

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

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

Member: filippg
filippg Aug 21, 2008 at 20:32:55 (UTC)
Goto Top
Hallo,

ich weiß jetzt nicht, ob das für dich hilfreich ist. Aber mit der Windows Powershell (quasi der Nachfolger der DOS-Shell) ist das kein Problem.
Mit der DOS-Shell kann ich das zumindest nicht. Problem: man müsste die Datei Zeilenweise durchlaufen und sich immer die vorherige noch merken. Ich weiß nicht, wie man in DOS die Datei zeilenweise durchläuft, und findstr akzeptiert als Eingabe ja auch nur Dateien, keine Strings.

Gruß

Filipp
Member: bastla
bastla Aug 21, 2008 at 20:46:47 (UTC)
Goto Top
Hallo lalaman und filippg!

Zur Not sollte es doch auch mit CMD zu machen sein face-wink (übrigens genau mit dem von filippg beschriebenen Algorithmus):
@echo off & setlocal
set "Muster=Muster"  
set "Quelle=D:\Liste.txt"  
set "Ziel=D:\Neue_Liste.txt"  

if exist "%Ziel%" del "%Ziel%"  
set Vorige=
for /f "usebackq delims=" %%i in ("%Quelle%") do call :ProcessLine "%%i"  
goto :eof

:ProcessLine
echo %~1|findstr /i "%Muster%">nul && (  
	if defined Vorige (
        >>"%Ziel%" echo %Vorige%  
        >>"%Ziel%" echo %~1  
    ) else (
        echo Keine Zeile vor %1 gefunden!
    )
)
set "Vorige=%~1"  
goto :eof
[Edit] Falls die im Beispiel angegebene Reihenfolge in der Zieldatei tatsächlich so gemeint sein sollte, müssten die Zeilen 14 und 15 getauscht werden. [/Edit]
Grüße
bastla
Member: lalaman
lalaman Aug 21, 2008 at 21:21:38 (UTC)
Goto Top
Hallo bastla und fillipg

die Lösung von bastla funktioniert soweit ganz gut.

Eine Kleinigkeit wäre allerdings noch: Wenn Sonderzeichen im durchsuchten Text vorhanden sind scheint es Probleme zu geben. Die Zeilen wurden nicht in die Neue_Liste.txt übernommen.

Nicht funktioniert hat es z.B. bei den Zeichen " und >

Wenn man das bei der Suche noch ignorieren lassen könnte wäre das wunderbar; ansonsten funktioniert das Script einwandfrei genau so wie ich es mir gedacht hatte.

Vielen Dank schon mal für die Mühen

Grüße
lalaman
Member: bastla
bastla Aug 21, 2008 at 22:11:31 (UTC)
Goto Top
Hallo!
Nicht funktioniert hat es z.B. bei den Zeichen " und >
Wenn Derartiges ins Spiel kommt, greife ich eigentlich tatsächlich lieber zu einer anderen Sprache (in meinem Fall VBS) - aber einen Versuch soll's wert sein:
@echo off & setlocal
set "Muster=Muster"  
set "Quelle=D:\Liste.txt"  
set "Ziel=D:\Neue_Liste.txt"  

if exist "%Ziel%" del "%Ziel%"  
set Vorige=
for /f "usebackq delims=" %%i in ("%Quelle%") do set "Zeile=%%i" & call :ProcessLine  
goto :eof

:ProcessLine
set "Zeile=%Zeile:>=^>%"  
set "Zeile=%Zeile:<=^<%"  
set "Zeile=%Zeile:"=§%"  
echo "%Zeile%"|findstr /i "%Muster%">nul && (  
	if defined Vorige (
        >>"%Ziel%" echo %Vorige:§="%  
        >>"%Ziel%" echo %Zeile:§="%  
    ) else (
        echo Keine passende Zeile vor %Zeile:§="% gefunden!  
    )
)
set "Vorige=%Zeile%"  
goto :eof
Grüße
bastla
Member: lalaman
lalaman Aug 22, 2008 at 12:34:44 (UTC)
Goto Top
Hey,

also ich hab die 2te Version jetzt nochmal ausprobiert es klappt aber leider immer noch nicht richtig.

Jetzt bleibt er beim &-Zeichen hängen.

Wie würde denn die vbs-Lösung aussehen bei der alle Sonderzeichen ignoriert werden?

Ich muss es ja nicht in Batch haben face-smile

Danke für die Mühen bis hier her

Grüße
lalaman
Member: bastla
bastla Aug 22, 2008 at 16:49:19 (UTC)
Goto Top
Hallo lalaman!

So knapp vor dem Ziel wirst Du doch wohl nicht aufgeben wollen ... face-wink

Füge vor Zeile 14 noch ein:
set "Zeile=%Zeile:&=^&%"  
und wenn Dir noch mehr von diesen ekelhaften Sonderzeichen (ich denke da vor allem an "|") begegnen sollten, kannst Du mit denen nach dem gleichen Muster verfahren.
Mit VBS ist der Aufwand ausnahmsweise etwas geringer als in Batch:
Quelle = "D:\Liste.txt"  
Ziel = "D:\Neue_Liste.txt"  
Muster = "Muster"  

Set fso = CreateObject("Scripting.FileSystemObject")  
Zeilen = Split(fso.OpenTextFile(Quelle).ReadAll, vbCrLF)
Set Z = fso.CreateTextFile(Ziel, True)
For i = 0 To UBound(Zeilen)
    If InStr(1, Zeilen(i), Muster, vbTextCompare) > 0 Then
        If i > 0 Then
            Z.WriteLine Zeilen(i - 1)
            Z.WriteLine Zeilen(i)
        Else
            WScript.Echo "Suchbegriff bereits in der ersten Zeile gefunden!"  
        End If
    End If
Next
Z.Close		
Grüße
bastla
Member: lalaman
lalaman Aug 23, 2008 at 09:01:17 (UTC)
Goto Top
Moin,

perfekt, die vbs-Lösung hat gleich funktioniert! Jetzt ignoriert er alle Zeichen...
Vielen Dank für die Hilfe face-smile


Grüße
lalaman
Member: lalaman
lalaman Jun 19, 2009 at 10:56:21 (UTC)
Goto Top
Hallo allerseits!

Das oben aufgeführte VBS Script funktioniert bei mir immer noch einwandfrei.

Jetzt hätte ich allerdings noch eine Ergänzungsfrage:
Ist es möglich das "Muster", das gesucht wird in Zeile 3, noch etwas anders zu definieren.

Ich hätte gerne, dass Zahlen gesucht werden; z.B. steht in dem Fließtext:

TextTextTextTextTextText
3 Männer arbeiten
TextTextTextTextTextText
15 Männer arbeiten
TextTextTextTextTextText
1382 Männer arbeiten
TextTextTextTextTextText

...ich möchte jetzt z.B. alle Zeilen mit 4 Männern haben und alle höheren Zahlen auch; also in diesem Fall die Zeilen mit 15 und 1382 Männern.

Der Rest des Scripts soll so bleiben...dass die Zeile davor mitkopiert wird usw.

Hoffe es war einigermaßen verständlich was ich möchte.
Wäre sehr nett, wenn mir nochmal jemand helfen könnte, weil ich wirklich null Ahnung von vbs habe face-sad

Viele Grüße
lalaman
Member: bastla
bastla Jun 19, 2009 at 13:38:43 (UTC)
Goto Top
Hallo lalaman!

Wenn ich das richtig verstanden habe (und das Suchschema immer "Zeilenanfang - ganze Zahl - Leerzeichen - Suchmuster" lautet), etwa so:
Quelle = "D:\Liste.txt"  
Ziel = "D:\Neue_Liste.txt"  

Min = 4
Muster = "Männer"  

Set rE = New RegExp
rE.IgnoreCase = True
rE.Pattern = "^(\d+) " & Muster  

Set fso = CreateObject("Scripting.FileSystemObject")  
Zeilen = Split(fso.OpenTextFile(Quelle).ReadAll, vbCrLF)
Set Z = fso.CreateTextFile(Ziel, True)
For i = 0 To UBound(Zeilen)
    If rE.Test(Zeilen(i)) Then
        Wert = rE.Execute(Zeilen(i))(0).SubMatches(0)
        If CInt(Wert) >= Min Then
            If i > 0 Then
                Z.WriteLine Zeilen(i - 1)
                Z.WriteLine Zeilen(i)
            Else
                WScript.Echo "Suchbegriff bereits in der ersten Zeile gefunden!"  
            End If
        End If
    End If
Next
Z.Close
Grüße
bastla

P.S.: Die Benachrichtigungsfunktion ist auch bei als "gelöst" markierten Beiträgen aktiv.
Member: lalaman
lalaman Jun 20, 2009 at 13:27:14 (UTC)
Goto Top
Guten Morgen!

Also erstmal Danke für die erneut schnelle Hilfe! Das Script funktioniert so wie von dir beschrieben ("Zeilenanfang - ganze Zahl - Leerzeichen - Suchmuster") perfekt.
Allerdings passt das mit dem Zeilenanfang noch nicht...also das Muster Zahl - Leerzeichen - Wort befindet sich im Text und nicht immer am Zeilenanfang...lässt sich das noch irgendwie einbauen?!

Grüße
lalaman
Member: bastla
bastla Jun 20, 2009 at 13:52:13 (UTC)
Goto Top
Hallo lalaman!

Für den Zeilenanfang "zuständig" ist das Zeichen "^" in der Zeile 9 - wenn Du dieses weglässt (die Zeile sähe dann so aus: )
rE.Pattern = "(\d+) " & Muster
wird das erste Vorkommen an beliebiger Stelle in der Zeile gesucht.

Grüße
bastla
Member: lalaman
lalaman Jun 20, 2009 at 14:17:48 (UTC)
Goto Top
Perfekt! Es funktioniert! face-smile

Ich bin mal wieder zu unendlichem Dank verpflichtet face-smile

Hätte ich nur mehr Ahnung von VB face-sad

Naja danke jedenfalls!

Grüße
lalaman
Member: Roachman
Roachman Apr 10, 2014 at 17:31:58 (UTC)
Goto Top
Guten Abend @ all,

bin nach einer suche auf diesen Thread gestoßen. Mein Ziel war aber nicht wie angegeben das Muster mit der Zeile davor in eine Datei zu exportieren, sondern diese beiden Zeilen in einem neuen Dokument zu löschen. Dank bastla konnte dies auch umgesetzt werden. Hier die Variante.
@echo off & setlocal
set "Muster=Muster"  
set "Quelle=D:\Liste.txt"  
set "Ziel=D:\Neue_Liste.txt"  

if exist "%Ziel%" del "%Ziel%"  
set "Vorige="  
for /f "usebackq delims=" %%i in ("%Quelle%") do call :ProcessLine "%%i"  
if defined Vorige >>"%Ziel%" echo %Vorige%  
goto :eof

:ProcessLine
echo %~1|findstr /i "%Muster%">nul && (  
    set "Vorige="  
) || (
    if defined Vorige >>"%Ziel%" echo %Vorige%  
    set "Vorige=%~1"  
    )
)
goto :eof

Vielen Dank an bastla

Roachman