Batch: Text zwischen zwei Klammern ausgeben, von Textdatei?

2 Antworten

oh man, Du bist echt hartneckig...

Das is doch echt simpel: Man setzt ein Zeichen, welches "jeder" sieht .

  • Lampe ist aus tue das eine
  • Lampe ist an tue was anderes
Aber wie könnte der Quellcode der Batch-Datei aussehen?

Du fummelst schon so lange an dem Parser herum. Ich habe Dich auch darauf hingewiesen, dass Batch die denkbar ungeeignetste Sprache für Dein Projekt ist.

Immerhin solltest Du jedoch inzwischen soviel über Batch wissen, das Du nicht mehr nach fertigen Quellcode fragen müsstest...🤔

@echo off
chcp 65001 >nul

for /f "usebackq tokens=*" %%a in ("test.txt") do (
    set "__Line=%%a"
    call :verarbeiteZeile
)
pause
exit /b


:verarbeiteZeile
  rem enthällt die Zeile eine {-Klammer? ...vergleich "%__Line% mit gelöschter {-Klammer" mit mit Original "%__Line%")
if "%__Line:{=%" neq "%__Line%" (
      rem setze ein Flag (Lampe an)
    set "inKlammer=1"
    echo Now in {-Block
    exit /b 0
)
  rem enthällt die Zeile eine }-Klammer? ...vergleich "%__Line% mit gelöschter }-Klammer" mit mit Original "%__Line%")
if "%__Line:}=%" neq "%__Line%" (
      rem lösche ein Flag (Lampe  aus)
    set "inKlammer="
    echo }-Block ends
    exit /b 0
)

  rem wass gemacht werden soll wenn das Flag gesetzt ist
if defined inKlammer (
    echo in KlammerBlock  : %__Line%

  rem was wenn nicht
) else (
    echo ausserhalb Klammerblock: %__Line%
)
exit /b

test.txt:

blah und blubb
{
Text1, der ausgeben werden soll....
Text2, der ausgeben werden soll....
Text3, der ausgeben werden soll....
}
hek und meck
miffmuf {
Wackelpudding
Götterspeise
}

https://ss64.com/nt/syntax-replace.html (siehe Abschitt: Boolean Test "does string exist ?")

Woher ich das weiß:eigene Erfahrung – Ich mach das seit 30 Jahren
GabrielBuie2006 
Fragesteller
 08.04.2020, 09:12

Also ... Ehrlichgesagt verstehe ich noch immer nicht so die For-Schleife. Ich weiss nicht warum!? Keine Ahnung warum. Ich tue mir somit auch jetzt gerade ziemlich im C# schwer.

Langsam glaube ich schon:

"Ich glaube ich höre mit Programmieren auf und nehme mir für meine 6 Instrumente Zeit, die ich halbwegs gut spielen kann."

0

Zunächst einmal musst du über die Datei iterieren indem du mit einer for-Schleife Zeile für Zeile liest:

for /F "usebackq delims=" %%L in ("%file%") do (
    echo current line content: %%L
)

Die Variable file muss dabei den Pfad der auszugebenden Datei angeben (Durch usebackq kann der Pfad in Anführungszeichen angegeben werden und darf somit auch Leerzeichen enthalten). Mithilfe von "delims=" verhinderst du das Aufteilen der Zeile an z.B. Leerzeichen. Schlussendlich wird der Code im do-Block der for Schleife n-mal aufgerufen, wobei n = Anzahl der Zeilen in der Datei %file%, jedes mal mit der n-ten Zeile als Inhalt der Variable %L.

Jetzt musst du nur noch eine Logik implementieren, die entscheidet wie mit einem bestimmten Inhalt der aktuellen Zeile %L verfahren werden soll. Ich bin mal von folgendem gewünschtem Verhalten ausgegangen:

  • Wurde vor der aktuellen Zeile eine Klammer geöffnet, so soll der Inhalt dieser ausgegeben werden ─ bis zu einer eventuell auftauchenden schließenden Klammer in der aktuellen Zeile.
  • Befinden wir uns aktuell nicht in einem von Klammern umschlossenem Block, so wird die Zeile nicht ausgegeben ─ bis zu einer eventuell auftauchenden öffnenden Klammer.

Um mehrere Blöcke innerhalb einer Zeile zu erkennen, muss das Prozedere in manchen Fällen mehrmals pro Zeile wiederholt werden, was das ganze etwas unübersichtlicher macht.

Die folgende Lösung deckt viele der möglichen Fällen ab:

@echo off

set "file=sample.txt"
set "isInBlock=false"

for /F "usebackq delims=" %%L in ("%file%") do (
    call :parseLine "%%~L"
)

pause
exit


:parseLine <lineContent: String> 
    set "_str2parse=%~1"
    if %isInBlock% equ true (
        goto _printUntilClose
    ) else (
        goto _notPrintUntilOpen
    )
exit /b

:_printUntilClose
    for /F "tokens=1* delims=}" %%a in ("#%_str2parse%") do (
        set "_tmp_a=%%a"
        call echo:%%_tmp_a:~1%%
        if "%_str2parse%" neq "%_str2parse:}=%" set "isInBlock=false"
        if "%%b" neq "" (
            set "_str2parse=%%b"
            goto _notPrintUntilOpen
        )
    )
exit /b
    
:_notPrintUntilOpen
    for /F "tokens=1* delims={" %%a in ("#%_str2parse%") do (
        if "%_str2parse%" neq "%_str2parse:{=%" set "isInBlock=true"
        if "%%b" neq "" (
            set "_str2parse=%%b"
            goto _printUntilClose
        )
    )
exit /b

Allerdings ist auch dies keine perfekte Lösung. Zum Beispiel funktionieren geschachtelte Blöcke ("a { b { c } d } e") nicht korrekt ─ hier müsste man die Anzahl der geöffneten Klammern mitzählen und immer mit beiden möglichen Klammern rechnen. (Falls du diese Funktion benötigst, kann ich dir auch dafür ein Skript schreiben, für diese Antwort würde das die Sache aber unnötig kompliziert machen.)

Ich hoffe ich konnte dir hiermit helfen, wenn du was nicht verstehst oder du einen Fehler im Code findest, antworte mir einfach hier :)

timlg07  08.04.2020, 21:02

Hätte vielleicht noch ein Beispiel mit dem generierten Output hinzufügen sollen... Also für eine Datei sample.txt mit dem Inhalt

0 00
{
 1 11
1.11

11.11
}

0.00{ 1.11.11

11.11.11
}00.00
{1.11.11.11 }0.00.00  {1_}
00.00.00 { 1_1 { 1_11 } x }

liefert mein Skript die Ausgabe

 1 11
1.11
11.11

 1.11.11
11.11.11

1.11.11.11
1_
 1_1 { 1_11
0