Per Batch Wert aus einem HTML Code auslesen?

2 Antworten

Beinahe hätte ich ich geantwortet "No Way" (in Batch), ...damit meiner Regel "geht nicht gibts nicht" widersprochen.

Html-Zeilen gelten in Batch, wegen der "<" und ">" als giftige Strings und lassen sich in Batch nur mit riesigem Aufwand überhaupt handhaben.

Batch ist in Sachen unvorhersehbare Texte definitiv kein guter Partner .

Find/Findstr können lediglich feststellen ob ein String in einem Text vorhanden ist, können aber nur ganze Zeilen zurückgeben, jedoch kein Suchmuster selektiv zurückgeben.

Batch ist um definierte Abläufe zu Steuern, mehr aber auch nicht.

mit Powershell und einer kleinen RegEx ist das ein Klacks.

demo1.ps1

$String  =  "<tr><td class='subtd'>DB2</td><td class='subtd'><nobr><font color=#fc7f2b><img title='Ich bin eine Datenbank' src='logo_ci.svg' width='14' height='14'> 12.3.666</font></nobr> <font color=grey title='Letztes Login (Monat.Jahr) auf dieser Datenbank'>XXX</font> </td></tr>"
  #gewagt! !!! im Lookbehind sind nur konstante Ausdrücke erlaubt!!! RegEx Lookbehind:(?<='14'\> ) =: (schau zurück ob "'14'>Leerzeichen" davor steht)
  # suche zuvor:    mindestens kein oder mehr Leerzeichen , mindestens eine Ziffer.mindestens eine Ziffer.mindestens eine Ziffer
$searchPattern="(?<='14'\> )\s*\d+\.\d+\.\d+"
  #als  Inputobjekt   kan auch eien Datei  dienen
Select-String $searchPattern -InputObject $String -AllMatches |%{
    'Folgender Treffer gefunden :'
    $_.matches.Value  #alle Teffer anzeigen
      #Zur Demo nur mal die komplete Match-Sruktur  anzeigen
    'Matchstruktur Demo:'
    $_|fl *
}
pause

Ein RegEx-Lookbehind ist eine heiße Sache und man muss schon sehr Sicher sein, dass exakt das gewünschte vor dem eigentlichen Match steht!

Einfacher ist es erst die nähere Umgebung des "Ziels" (mit einer "ungefähren" Definition komplett zu erfassen, und in einem zweiten Schritt das genaue Match zu selektieren:

$String  =  "<tr><td class='subtd'>DB2</td><td class='subtd'><nobr><font color=#fc7f2b><img title='Ich bin eine Datenbank' src='logo_ci.svg' width='14' height='14'> 12.3.666</font></nobr> <font color=grey title='Letztes Login (Monat.Jahr) auf dieser Datenbank'>XXX</font> </td></tr>"
$BereichPattern = "width=.\d+.\s+height=.\d+.>\s*\d+\.\d+\.\d+\s*</font>"
$VersionPattern = "\d+\.\d+\.\d+"
$Version = Select-String $BereichPattern -InputObject $String -AllMatches |%{
    $_.matches.Value|%{
        Write-Host ('Folgender Bereich gefunden : {0}' -f $_) -fo green
        Write-Host ('filtere VersionPattern: {0}' -f $VersionPattern) -fo green
       (Select-String $VersionPattern -InputObject $_).matches.Value
    }
}
$Version
pause

Natürlich ist das nur ein kleiner Teil , dessen was getan werden muss.

...und soll nur zeigen, wie man mit inhomogenem Text und RegEx auf die Suche geht.

Etwas muss auch für Dich übrig bleiben. Ob Du nun den perfekten Umgang mit der alten BatchSprache lernst, oder Dich gleich dem modernen PowerShell widmest macht im Lernaufwand den Kohl auch nicht fett.

In jedem Fall gibt es bei richtigem Umgang mit PS keine Probleme mit dem zu verarbeitendem Stoff.

Ich könnte Dir auch das ganze Ding schreiben, aber dann wär's Honorararbeit🤑... (Niemand arbeitet zum Spaß mit Datenbanken ergo machst Du solchen Quatsch für eine Firma?)

Woher ich das weiß:eigene Erfahrung – Ich mach das seit 30 Jahren
Joergsabbah 
Fragesteller
 26.10.2021, 21:11

Erst einmal vielen Dank für die ganze Mühe und man bin ich froh über dein Mantra 😂

Um deine letzte Frage vorwegzunehmen: ich mach den Quatsch für mich innerhalb einer Firma 😅 unser Sysadmin hat die Ausführung jeder Exe geblockt, die nicht ge"whitelisted" ist.

Um mir meine Arbeit zu erleichtern, habe ich angefangen (während freier Spitzen) mit Boardmitteln Batch files zur Automatisierung zu schreiben.

Ich werde morgen mal deine Vorschläge versuchen umzusetzen 😅

Und ja ich weiß das Powershell wesentlich mächtiger ist, aber ich hab damit leider noch gar keine Erfahrung 😐

Bisher beschränkt sich mein Wissen auf SQL, C, C++ und eben Batch 😄

0
Erzesel  26.10.2021, 22:22
@Joergsabbah

Ok mein Hund war Gassi und ich hab nichts weiter vor...:

Wenn Du in anderen Sprachen fit bist , kann ich mir sparen Kleinkram zu erklären.

Powershell ist extrem Flexibel was Variablen und Datentypen angeht. $DBTrefferZeilen kann ein String sein, oder aber eine Collection.

PS verwendet automatisch die Passende Methode für den Typ. gib Gas...

html.txt

<tr><td class='subtd'>DB1</td><td class='subtd'><nobr><font color=#fc7f2b><img title='Ich bin eine Datenbank' src='logo_ci.svg' width='14' height='14'>8.55.3</font></nobr> <font color=grey title='Letztes Login (Monat.Jahr) auf dieser Datenbank'>XXX</font> </td></tr>
<tr><td class='subtd'>DB2</td><td class='subtd'><nobr><font color=#fc7f2b><img title='Ich bin eine Datenbank' src='logo_ci.svg' width='14' height='14'> 6.777.12</font></nobr> <font color=grey title='Letztes Login (Monat.Jahr) auf dieser Datenbank'>XXX</font> </td></tr>

demo.ps1

$DBPatern="class='subtd'>DB1</td>" # Pattern für Zeilen mit Der gewünschten Datenbank (DB1)
$BereichPattern = "width=.\d+.\s+height=.\d+.>\s*\d+\.\d+\.\d+\s*</font>"
$VersionPattern = "\d+\.\d+\.\d+"
 # datei einlesen und Zeilen auf den  Datenbankpattern filtern
$DBTrefferZeilen=gc 'html.txt'|?{$_ -match $DBPatern}
 #mal Anzeigen
$DBTrefferZeilen|%{ Write-Host ('DatenbankZeile gefunden: {0}' -f $_) -f blue}
 #wieder der "Rundumblick" um die Versionsnummer
$Version = Select-String $BereichPattern -InputObject $DBTrefferZeilen -AllMatches |%{
  $_.matches.Value|%{
    Write-Host ('Folgender Bereich gefunden : {0}' -f $_) -fo green
    Write-Host ('filtere VersionPattern: {0}' -f $VersionPattern) -fo green
    (Select-String $VersionPattern -InputObject $_).matches.Value
  }
}
$Version
switch ( $Version )
{   #Programm ausführen abhängig von Versionnummer
  '8.55.3'  { &'C:\mein Pfad\mein Programm' '"Parameter mit Spaces" blahOhne' }
  '16.245.66' { &'C:\mein Pfad\anderes Programm'}
}
pause
0

Zur Lösung dieses Problems, ohne etwas an den Rahmenbedingungen zu ändern, musst du einen Regex verwenden, auch bekannt als regulärer Ausdruck. Damit kannst du ein Muster angeben, nachdem in einer Datei gesucht wird. Bestimmte Felder können damit auch ausgelesen werden. Du brauchst also ein Match auf die Zeile mit der richtigen Datenbank und dann matcht du die Versionsnummer in dieser Zeile.

Joergsabbah 
Fragesteller
 26.10.2021, 15:40

Ok, ich bin jetzt so weit, dass ich weiß wie ich die Stelle suche lassen:

Findstr "'14'>.*</font>" Datenbankuebersicht.txt

.* müsste in dem Fall quasi der Platzhalter für die Version sein.

Aber wie mache ich jetzt ein Abfrage, in der er mir

1. Die Zeile mit der Datenbank sucht

Und 2. Den Wert für .* ausgibt?

0
palindromxy  26.10.2021, 15:47
@Joergsabbah

DB1 oder DB2 als Variable in das Pattern und die Versionsnummer als gematchte Gruppe extrahieren. Vielleicht ist findstr aber auch etwas grob dafür. Mach sowas zum Glück nur unter Linux.

0