Erledigt Suchen und Ersetzen in Batch-Datei

Dieses Thema im Forum "Tech & FAQ Forum" wurde erstellt von vlintstoun, 9 März 2020.

  1. vlintstoun

    vlintstoun mit Glied

    Registriert seit:
    22 April 2001
    Beiträge:
    1.068
    Hi

    Ich habe eine Textdatei mit folgendem Inhalt:
    Code:
    AAA
    BBB
    CCC
    DDD
    EEE
    FFF
    Ich möchte nun mit einer Batch-Datei nach 'BBB' suchen und durch den Inhalt einer zweiten Textdatei ersetzen. Die zweite Textdatei hat folgenden Inhalt:
    Code:
    BBB
    bba
    bbb
    bbc
    bbd
    bbe
    bbf
    ...
    
    Das Resultat sollte also folgendermassen aussehen:
    Code:
    AAA
    BBB
    bba
    bbb
    bbc
    bbd
    bbe
    bbf
    ...
    CCC
    DDD
    EEE
    FFF
    Alle Befehle oder Tools, die ich kenne, basieren auf Strings. Da die zweite Textdatei sehr umfangreich ist (ca. 20MB), komme ich damit nicht weiter.
    Bin für alle Vorschläge offen, egal ob Batch- oder PowerShell-Befehle, externe Kommandozeilen-Tools usw.

    Have fun
    Vlintstoun
  2. DSmdM_G

    DSmdM_G Bekanntes Mitglied

    Registriert seit:
    3 Juni 2001
    Beiträge:
    1.497
    Hallo,

    wenn die erste Datei nicht so groß ist an der gesuchten Stelle in zwei Teile splitten.

    Dann in der Eingabeaufforderung:
    type Datei1a > Dummy.txt
    type Datei2 >> Dummy.txt
    type Datei1b >> Dummy.txt


    Ansonsten,
    erste Datei öffnen und zeilenweise einlesen,
    wenn Zeile nicht gesuchte ist die Zeile in Dummy Datei ausgeben,
    wenn Zeile gesuchte ist zweite Datei öffnen, ganz oder zeilenweise einlesen und an Dummy Datei anhängen
    Rest von erster Datei zeilenweise einlesen und an Dummy Datei anhängen


    Gruß
    Maus-Gucker
    vlintstoun sagt Danke.
  3. dr_tommi

    dr_tommi alter Oldie

    Registriert seit:
    26 April 2001
    Beiträge:
    13.542
    Nur mal so quick and dirty gedacht. Sehr quick und sehr sehr dirty. ;)
    Ich persönlich würde die erste Datei zeilenweise lesen lassen, und wenn nicht der gesuchte String gelesen wurde, diese Zeile in eine dritte Datei zu schreiben, z.B. mit "echo zeile >> 3.txt".
    Wenn der gesuchte String gefunden wurde, dann wird nicht der String sondern der Inhalt der zweiten Datei an die dritte angehängt. Irgendwas mit cat 2.txt >> 3.txt oder so.
    Danach geht es weiter mit dem zeilenweisen Lesen der ersten Datei.

    Nur mal so als erster Ansatz.
    Das geht bestimmt schöner.
    vlintstoun sagt Danke.
  4. vlintstoun

    vlintstoun mit Glied

    Registriert seit:
    22 April 2001
    Beiträge:
    1.068
    Hi

    Danke, das könnte gehen, denn 'BBB' bzw. das Suchwort kommt nur einmal vor. Ich probier mal aus, wie ich die erste Datei aufteilen kann.

    Have fun
    Vlintstoun
  5. vlintstoun

    vlintstoun mit Glied

    Registriert seit:
    22 April 2001
    Beiträge:
    1.068
    Hi

    Habe eine Batch gebastelt, die mit kleineren Testdaten perfekt funktioniert. Wenn ich jedoch die mehrere MB grossen Original-Dateien verwende, dauert die Verarbeitung ewig.
    Ich versuche nun mal die Arbeitsschritte mit der PowerShell nachzubilden. da muss ich mich aber zuerst einlesen.

    Have fun
    Vlintstoun
  6. GiveThatLink

    GiveThatLink Bekanntes Mitglied

    Registriert seit:
    25 Oktober 2009
    Beiträge:
    588
    Weil Batch nur mal arschlahm ist - und es ist nur eine Anweisungsliste (AWL), du rufst immer nur andere Programme nach AWL auf, das frisst Zeit. Bei PS müsste alles im Interpreter bleiben, aber für echte Perfomance solltest du auf ein noch höheres Level gehen wie zB Autoit und das Script kompilieren. Oder gleich VC.
    vlintstoun sagt Danke.
  7. vlintstoun

    vlintstoun mit Glied

    Registriert seit:
    22 April 2001
    Beiträge:
    1.068
    Hi

    Danke für die Hinweise bezüglich Performance. Ich habe es mit PS und der Funktion "Replace" realisieren können. Das Skript rufe ich aus einer Batch-Datei auf und braucht ca. 20s, was nicht berauschend, aber für mich im Moment annehmbar ist.
    AutoIt kenne ich, wäre aber nicht darauf gekommen, dieses zu verwenden. Wenn mir mal langweilig ist, versuche ich mein Skript für AutoIt umzuschreiben.

    Have fun
    Vlinstoun
  8. vlintstoun

    vlintstoun mit Glied

    Registriert seit:
    22 April 2001
    Beiträge:
    1.068
    Hi

    Inzwischen konnte ich mein PS-Skript erheblich beschleunigen, indem ich das Einlesen der Datei mit "Get-Content" um den Switch "-Raw" erweitert habe. Dadurch werden Zeilenumbrüche ignoriert und der Dateiinhalt wird, statt in einem Array, in einer einzigen Stringvariablen gespeichert. Jetzt läuft das Skript noch <1s.

    Have fun
    Vlintstoun
    jr33 sagt Danke.
  9. RichyZuHause

    RichyZuHause Alter mit Ego

    Registriert seit:
    2 Juni 2001
    Beiträge:
    2.006
    Hallo Steinflinte.
    Lässt Du uns an Deinen Erkenntnissen teilhaben?
    .cmd oder .ps1?
    Wir lernen ja gerne nie aus.
    ultimate sagt Danke.
  10. vlintstoun

    vlintstoun mit Glied

    Registriert seit:
    22 April 2001
    Beiträge:
    1.068
    Hi

    Klar, kann ich machen. Wie bereits erwähnt, rufe ich das PowerShell-Skript aus einer Batch-Datei auf, womit auch gleich die Sicherheitseinstellungen von PS umgangen werden:icon_lol::
    Code:
    PowerShell.exe -ExecutionPolicy Bypass -file pfad\skriptname.ps1
    Das PS-Skript sieht auf mein obiges Beispiel bezogen folgendermassen aus, wobei ich nach der Zeichenfolge "BBB.*CCC" suche, da sich in meinen realen Daten dazwischen noch weiterer Text befinden kann, der ebenfalls durch den Inhalt der 2. Textdatei ersetzt werden soll:
    Code:
    $InName =  Get-Content -path "pfad\erste.txt" -Raw
    $ReplaceText = Get-Content -path "pfad\zweite.txt" -Raw
    $OutName = "pfad\resultat.txt"
    
    $InName -Replace "(?s)BBB.*CCC", $ReplaceText | Set-Content -Path $OutName
    Dazu muss in der Datei "zweite.txt" zuunterst noch ein "CCC" eingefügt werden. ".*" ist der reguläre Ausdruck für beliebiges Zeichen ohne Zeilenumbruch in beliebiger Anzahl. Damit Zeilenumbrüche auch berücksichtigt werden, muss "(?s)" vorangestellt werden.

    Ich hoffe, dass das einigermassen verständlich ist.

    Have fun
    Vlintstoun
    GiveThatLink, ultimate und RichyZuHause sagen Danke.
  11. RichyZuHause

    RichyZuHause Alter mit Ego

    Registriert seit:
    2 Juni 2001
    Beiträge:
    2.006
  12. dr_tommi

    dr_tommi alter Oldie

    Registriert seit:
    26 April 2001
    Beiträge:
    13.542
    Das ist schon sehr speziell. Die Ausgangssituation doch aber so, dass du nur BBB suchen und ersetzen wolltest.
    Jetzt wird plötzlich alles zwischen BBB und CCC ersetzt.
    Außerdem setzt du voraus, dass BBB und CCC tatsächlich in dieser Reihenfolge in der Datei vorhanden sind und musst zusätzlich noch CCC in die zweite Datei schreiben damit auch CCC wieder in der Zieldatei enthalten ist. Und wenn du normale Dateien hast, die nach jedem Eintrag einen Zeilenwechsel haben, hat deine Ergebnisdatei eine zusätzliche Leerzeile nach CCC
    Für deine spezielle Anwendung mag das ok sein, allgemein verwendbar ist das so nicht.
  13. vlintstoun

    vlintstoun mit Glied

    Registriert seit:
    22 April 2001
    Beiträge:
    1.068
    Das ist mir schon klar. Ich habe eine sehr umfangreiche, über Jahre gewachsene Batch-Datei (die Ursprünge reichen mehr als 15 Jahre zurück), in der das daraus aufgerufene PS-Skript nur ein Mosaiksteinchen darstellt.

    Die Batch hat mir immer gute Dienste geleistet, aber ich musste mit der Zeit immer mehr externe Kommandozeilen-Programme wie wget, blat usw. einbinden, um den Funktionsumfang zu erweitern. Nun stosse ich mit meiner bisherigen Vorgehensweise aber an Grenzen.

    Ich möchte nun versuchen, meine Batch Schritt für Schritt auf PowerShell-Befehle umzubauen, sodass am Ende ein reines PS-Skript vorhanden ist. Ich bin PowerShell-Anfänger und mit diesem Projekt mache ich Learning-by-doing.
    Habe nie etwas anderes behauptet. Deshalb wollte ich meine Lösung auch nicht veröffentlichen, aber da Richy danach gefragt hat, habe ich sie dann doch gepostet.

    Have fun
    Vlintstoun
    Zuletzt bearbeitet: 1 April 2020 um 14:29
    RichyZuHause und Dorwyn sagen Danke.