calim3ro
Goto Top

In einem File nach Zeilenblöcken suchen und Zeilen hinzufügen. (CMD, Pearl,VCS)

Hallo ihr schlauen Köpfe

Zuerst: Ich habe nur wenig Ahnung von Programierung.

Zur Situation:

Ich habe ein grosses File (1,5 GB) mit Zeichenblöcken.

Diese sehen folgendermasen aus:

11 AAAAAAA
22 BBBBBBB
33 CCCCCCC
44 DDDDDDD
55 EEEEEEE

11 FFFFFFFF
22 GGGGGG
44 JJJJJJJJJJ
55 KKKKKKK

Ein Zeichenblock fängt immer mit 11 an.

Nun möchte ich folgendes tun:

Das File durchsuchen und Zeichenblöcke die ein 11 und 33 beinhalten, die Information hinter dem 11 unten an den Block schreiben. Vor dieser Information soll immer 99 stehen.

Falls in einem Block kein 33 vorkommt, muss dieser unverändert bleiben.

Am Ende soll das obere Beispiel folgendermasen aussehen:

11 AAAAAAA
22 BBBBBBB
33 CCCCCCC
44 DDDDDDD
55 EEEEEEE
99 AAAAAAA

11 FFFFFFFF
22 GGGGGG
44 JJJJJJJJJJ
55 KKKKKKK

Bevorzugte Skripts sind Pearl oder VCS, bin aber auch offen für andere Formate.

Ich hoffe ich konnte das gewünschte Vorgehen gut beschreiben, bei Unklarheiten einfach nachfragen.

Besten Dank an alle, die sich meinem Problem annehmen und etwas beisteuern können.

Gruss Calimero

Content-Key: 210597

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

Printed on: April 19, 2024 at 09:04 o'clock

Member: falscher-sperrstatus
falscher-sperrstatus Jul 04, 2013 at 20:57:37 (UTC)
Goto Top
Hallo,

1. Frage: Einmalig, oder nicht?
2., falls ersteres @1: Notepad++?

Grüße
Member: bastla
bastla Jul 04, 2013 updated at 22:40:43 (UTC)
Goto Top
Hallo Calim3ro!

Unter der Annahme, dass jeder Block mit einer Leerzeile endet (und die letzte Zeile der Datei ebenfalls leer ist) und die Blöcke keine "besonderen" Sonderzeichen enthalten, könnte das als Batch etwa so gehen (laufen wird's bei der Dateigröße eher nicht face-wink):
@echo off & setlocal
set "Ein=D:\Datei.txt"  
set "Aus=D:\Datei_neu.txt"  

(for /f "tokens=1* delims=: " %%i in ('findstr /n "^" "%Ein%"') do (  
    for /f "tokens=1*" %%a in ("%%j") do (  
        if "%%a"=="11" set "Wert=%%b"  
        if "%%a"=="33" if defined Wert set "Schreiben=true"  
    )
    if "%%j"=="" if defined Schreiben (  
        setlocal enabledelayedexpansion
        echo 99 !Wert!
        endlocal
        set "Schreiben="  
        set "Wert="  
    )
    echo(%%j
))>"%Aus%"  
if defined Schreiben >>"%Aus%" echo 99 %Wert%  
Alternative (setzt keine Leerzeile am Ende des Blocks voraus, erzeugt aber eine im Ergebnis - falls nicht gewünscht, Zeile 14 entfernen):
@echo off & setlocal
set "Ein=Datei.txt"  
set "Aus=Datei_neu.txt"  

(for /f "usebackq delims=" %%i in ("%Ein%") do (  
    for /f "tokens=1*" %%a in ("%%i") do (  
        if "%%a"=="11" (  
            if defined Schreiben (
                setlocal enabledelayedexpansion
                echo 99 !Wert!
                endlocal
                set "Schreiben="  
            )
            if defined Wert echo(
            set "Wert=%%b"  
        )
        if "%%a"=="33" set "Schreiben=true"  
    )
    echo(%%i
))>"%Aus%"  
if defined Schreiben >>"%Aus%" echo 99 %Wert%  
Grüße
bastla

[Edit] Berücksichtigung des letzten Blocks ergänzt und Alternativvariante hinzugefügt [/Edit]
Member: Calim3ro
Calim3ro Jul 05, 2013 at 17:43:05 (UTC)
Goto Top
Hallo certifiedit

Zur Frage 1: nicht einmalig, bis zum Ende der Datei.

Somit ergibt sich Frage 2.

Gruss Calim3ro
Member: Calim3ro
Calim3ro Jul 05, 2013 at 18:13:45 (UTC)
Goto Top
Hallo bastla

Besten Dank für Deine Bemühungen. Wie immer flott und kompetent unterwegs.

Konnte Deine 2te Version bestens verwenden. (ohne Linie 14, da keine Leerzeile am Ende erwünscht.)

Noch sind ein paar Anpassungen nötig, daher 2 Zusatzfragen:

1. Was muss ich anpassen, damit die neue Zeile nicht ans Ende des Blocks geschrieben wird, sondern unter die Zeile welche mit 11 beginnt?

2. Ist es möglich, die Positionen 10-15 der 11er-Zeile auszuwerten und den Wert mit einer Positivliste (separates File) zu verleichen.
Nur wenn dieser Wert auch in der Positivliste enthalten ist soll die 99-er Zeile ausgegeben werden.

Bei Fragen oder Unklarheiten einfach nachfragen.

Besten Dank im Voraus.

Gruss Calim3ro
Member: bastla
bastla Jul 05, 2013 updated at 20:04:38 (UTC)
Goto Top
Hallo Calim3ro!

In Batch ist das "Vorausschauen" (ob im Block eine Zeile mit "33" folgt) bereits nach der "11"-Zeile etwas tricky - in VBS geht's leichter:
Ein = "D:\Datei.txt"  
Aus = "D:\Datei_neu.txt"  
Liste = "D:\Positivliste.txt"  

Kenn = "11"  
Kenn2 = "33"  
Einf = "99"  
PStart = 10
PEnde = 15

KLen = Len(Kenn) 'Längen der Teilstrings vor der Schleife ...  
PLen = PEnde - PStart + 1 '... und damit nur einmal berechnen  

Mark = "§§§" 'Platzhalter für einzufügende Zeile; darf in der zu verarbeitenden Datei nicht enthalten sein  

Set fso = CreateObject("Scripting.FileSystemObject")  
Set E = fso.OpenTextFile(Ein)
Set A = fso.CreateTextFile(Aus)

'Positivliste so in Variable einlesen, dass jeder Eintrag durch eine Zeilenschaltung begrenzt ist  
L = vbNewline & fso.OpenTextFile(Liste).ReadAll & vbNewLine 

Do While Not E.AtEndOfStream
    Z = E.ReadLine
    If Left(Z, KLen) = Kenn Then 'Blockbeginn?  
        If Krit1 * Krit2 = 1 Then 'wenn beide Kriterien erfüllt sind ...  
            '... Block schreiben und dabei Zusatz-Zeile für Platzhalter (lt Var "Mark") einsetzen ...  
            A.Write Replace(Block, Mark, vbNewline & Einf & Wert)
        Else ' ... ansonsten ...  
            A.Write Replace(Block, Mark, "") '... Platzhalter vor dem Schreiben rückstandsfrei entfernen  
        End If
        If Wert <> "" Then 'ab zweitem Block ...  
            '... neuen Block mit Zeilenschaltung (vorhergehender Block endet ohne Zeilenschaltung) beginnen  
            Block = vbNewLine & Z & Mark
        Else
            Block = Z & Mark
        End If
        Wert = Mid(Z, KLen + 1)
        'Teilstring in "L" (Liste) suchen und Ergebnis als 0 oder 1 speichern  
        Krit1 = Sgn(InStr(L, vbNewline & Mid(Z, PStart, PLen) & vbNewline))
        Krit2 = 0 'Kriterium Kennung 2 rücksetzen  
    Else
        Block = Block & vbNewline & Z 'Zeile an Block mit Zeilenschaltung anfügen  
    End If
    If Left(Z, KLen) = Kenn2 Then Krit2 = 1 'auf 2. Kriterium ("33") prüfen  
Loop

'letzten Block verarbeiten  
If Krit1 * Krit2 = 1 Then 'wenn beide Kriterien erfüllt sind ...  
    '... Block schreiben und dabei Zusatz-Zeile für Platzhalter (lt Var "Mark") einsetzen ...  
    A.Write Replace(Block, Mark, vbNewline & Einf & Wert)
Else ' ... ansonsten ...  
    A.Write Replace(Block, Mark, "") '... Platzhalter vor dem Schreiben rückstandsfrei entfernen  
End If
Die Datei mit derm Positivliste muss jeden (6-stelligen) Vergleichswert in einer eigenen Zeile enthalten. Beim Vergleich wird Groß-/Kleinschreibung berücksichtigt.

Grüße
bastla
Member: Calim3ro
Calim3ro Jul 06, 2013 at 13:49:46 (UTC)
Goto Top
Hallo bastla

Funktioniert ausgezeichnet! Besten Dank für Deine Hilfe und Bemühungen.

Schönes Wochenende.

Gruss Calim3ro
Mitglied: 76109
76109 Jul 07, 2013 updated at 14:15:09 (UTC)
Goto Top
Hallo zusammen!

Und zur Ergänzung noch die Kurzform:
Const sFileEin = "E:\Eingabe.txt"  
Const sFileAus = "E:\Ausgabe.txt"  
Const sFileListe = "E:\Liste.txt"  

Const iTestPos = 10
Const iTestLen = 6

Set oFso = CreateObject("Scripting.FileSystemObject")  
    
sTest = vbCrLf & oFso.OpenTextFile(sFileListe).ReadAll
aText = Split(vbCrLf & oFso.OpenTextFile(sFileEin).ReadAll, vbCrLf & "11")  
    
For i = 1 To UBound(aText)
    If aText(i) <> "" Then  
        sTarget = "11" & Split(aText(i), vbCrLf)(0)  
        sSearch = vbCrLf & Mid(sTarget, iTestPos, iTestLen)
        
        If InStr(aText(i), vbCrLf & "33 ") > 0 And InStr(sTest, sSearch) > 0 Then  
            aText(i) = sTarget & vbCrLf & "99" & aText(i)  
        Else
            aText(i) = "11" & aText(i)  
        End If
    End If
Next
    
oFso.CreateTextFile(sFileAus).Write Mid(Join(aText, vbCrLf), 3)

Gruß Dieter
Member: bastla
bastla Jul 07, 2013 at 15:27:36 (UTC)
Goto Top
Hallo Dieter!
Und zur Ergänzung noch die Kurzform:
Hätte ich eigentlich auch so ähnlich vorgehabt - aber wegen
Ich habe ein grosses File (1,5 GB) mit Zeichenblöcken.
dann doch die hinsichtlich RAM weniger anspruchsvolle Variante gewählt ...

Grüße
bastla
Mitglied: 76109
76109 Jul 07, 2013, updated at Jul 08, 2013 at 07:18:57 (UTC)
Goto Top
Hallo bastla!

Hinsichtlich der Dateigröße würde ich Dein Script auch bevorzugen. Mein Script (getestet) funktioniert nur mit kleineren Dateien..face-wink

Gruß Dieter

[edit]
Hab mal getestet und es hakt schon beim Versuch eine 576 MB-Datei in einen String einzulesen. Notepad und Notepad++ packens auch nichtface-sad

Und das trotz verfügbarem physikalischen Arbeitsspeicher von ca. 2,6 GB?

So sollte es dann auch mit überdimensionierten Dateien funktionieren:
Const sFileEin = "E:\Eingabe.txt"  
Const sFileAus = "E:\Ausgabe.txt"  
Const sFileListe = "E:\Liste.txt"  

Const iFindPos = 10
Const iFindLen = 6

Set oFso = CreateObject("Scripting.FileSystemObject")  
Set oList = CreateObject("Scripting.Dictionary")  

Set oFileEin = oFso.OpenTextFile(sFileEin)
Set oFileAus = oFso.CreateTextFile(sFileAus)

sComp = vbCrLf & oFso.OpenTextFile(sFileListe).ReadAll

Do Until oFileEin.AtEndOfStream
    sText = oFileEin.ReadLine
    
    If Left(sText, 2) = "11" Then  
        oList.Add "11", sText  
        oList.Add "99", "99" & Mid(sText, 3)  
    ElseIf sText <> "" Then  
        oList.Add Left(sText, 2), sText
    End If
    
    If sText = "" Or oFileEin.AtEndOfStream = True Then  
        If oList.Exists("11") Then  
            sFind = vbCrLf & Mid(oList.Item("11"), iFindPos, iFindLen)  
            If oList.Exists("33") = False Or InStr(sComp, sFind) < 1 Then  
                oList.Remove "99"  
            End If
        End If
        If oFileEin.AtEndOfStream Then sFreeLine = "" Else sFreeLine = vbCrLf  
        oFileAus.Write Join(oList.Items, vbCrLf) & vbCrLf & sFreeLine
        oList.RemoveAll
    End If
Loop

oFileEin.Close:  oFileAus.Close
[/edit]
Member: Calim3ro
Calim3ro Jul 14, 2013 at 15:14:09 (UTC)
Goto Top
Guten Tag zusammen

Hallo bastla

Zum VB-Skript von bastla am 05.07.2013 um 22:04 Uhr habe ich noch 2 Fragen.

Erstens:

Ist es möglich, die Dateien "Ein", "Aus" und "Positivliste" beim Aufruf von VB-Skript in cmd mitzugeben?

Ungefähr so:

call Script.vbs -D:\Datei.txt -D:\Datei_Neu.txt -D:\Positivliste.txt

Zweitens:

Wenn im Block die Kritik 1 und 2 (Zeile 11 & 33 im Beispiel) erfüllt wurden und die Zeile 99 geschrieben wird, sollte aus der Zeile 44 (ist im jedem Block enthalten) die Information der Position 5-9 hinter die Zeile 99 eingefügt werden.

Das würde demzufolgen so aussehen:

11 AAAAAAA
22 BBBBBBB
33 CCCCCCC
44 DDDDDDD
55 EEEEEEE
99 AAAAAAA DDDD (<---- geschriebene Information aus Zeile 11 und 44, wenn positiv auf Liste.txt in der Zeile 33)

Bei Unklarheiten einfach nachfragen.

Besten Dank für eure Hilfe und Bemühungen.

Gruss Calim3ro
Mitglied: 76109
76109 Jul 14, 2013 updated at 18:06:59 (UTC)
Goto Top
Hallo Calim3ro!

Der Cmd-Aufruf sollte gehen, indem Du in bastlas Script die Codezeilen 1-3 entfernst und die Codezeile 16 durch diese Codezeilen ersetzt:
With WScript.Arguments
    If .Count <> 3 Then
        WScript.Echo "Falsche Anzahl an Argumenten!":  WScript.Quit 1  
    Else
        Ein = .Item(0):  Aus = .Item(1):  Liste = .Item(2)
    End If
End With

Set fso = CreateObject("Scripting.FileSystemObject")  

If Not fso.FileExists(Ein) Or Not fso.FileExists(Aus) Or Not fso.FileExists(Liste) Then
    WScript.Echo "Datei nicht gefunden!":  WScript.Quit 1  
End If
Und im Cmd-Script in etwa so:
@echo off & setlocal

set "VbsScript=C:\Tools\Mein Script.vbs"  
set "DateiEin=C:\Mein Verzeichnis\Eingabe.txt"  
set "DateiAus=C:\Mein Verzeichnis\Ausgabe.txt"  
set "DateiListe=C:\Mein Verzeichnis\Liste.txt"  

CScript //nologo "%VbsScript%" "%DateiEin%" "%DateiAus%" "%DateiListe%"  

Gruß Dieter
Member: bastla
bastla Jul 14, 2013 updated at 18:35:01 (UTC)
Goto Top
Hallo Calim3ro und Dieter!

Die angepasste (aber völlig ungetestete) Version des Scripts könnte dann so aussehen:
Kenn =    "11"  
Kenn2 =   "33"  
P2Start = 10
P2Ende =  15
Kenn3 =   "44"  
P3Start = 5
P3Ende =  9
Einf =    "99"  

With WScript.Arguments
    If .Count <> 3 Then
        WScript.Echo "Falsche Anzahl an Argumenten!"  
        WScript.Quit 1
    Else
        Ein =   .Item(0)
        Aus =   .Item(1)
        Liste = .Item(2)
    End If
End With

KLen = Len(Kenn) 'Längen der Teilstrings vor der Schleife ...  
P2Len = P2Ende - P2Start + 1 '...  
P3Len = P3Ende - P3Start + 1 '... und damit nur einmal berechnen  

Mark = "§§§" 'Platzhalter für einzufügende Zeile; darf in der zu verarbeitenden Datei nicht enthalten sein  

Set fso = CreateObject("Scripting.FileSystemObject")  
Set E = fso.OpenTextFile(Ein)
Set A = fso.CreateTextFile(Aus)

'Positivliste so in Variable einlesen, dass jeder Eintrag durch eine Zeilenschaltung begrenzt ist  
L = vbNewline & fso.OpenTextFile(Liste).ReadAll & vbNewLine 

Do While Not E.AtEndOfStream
    Z = E.ReadLine
    If Left(Z, KLen) = Kenn Then 'Blockbeginn?  
        If Krit1 * Krit2 = 1 Then 'wenn beide Kriterien erfüllt sind ...  
            '... Block schreiben und dabei Zusatz-Zeile für Platzhalter (lt Var "Mark") einsetzen ...  
            A.Write Replace(Block, Mark, vbNewline & Einf & Wert)
        Else ' ... ansonsten ...  
            A.Write Replace(Block, Mark, "") '... Platzhalter vor dem Schreiben rückstandsfrei entfernen  
        End If
        If Wert <> "" Then 'ab zweitem Block ...  
            '... neuen Block mit Zeilenschaltung (vorhergehender Block endet ohne Zeilenschaltung) beginnen  
            Block = vbNewLine & Z & Mark
        Else
            Block = Z & Mark
        End If
        Wert = Mid(Z, KLen + 1)
        'Teilstring in "L" (Liste) suchen und Ergebnis als 0 oder 1 speichern  
        Krit1 = Sgn(InStr(L, vbNewline & Mid(Z, P2Start, P2Len) & vbNewline))
        Krit2 = 0 'Kriterium Kennung 2 rücksetzen  
    Else
        Block = Block & vbNewline & Z 'Zeile an Block mit Zeilenschaltung anfügen  
    End If
    If Left(Z, KLen) = Kenn2 Then Krit2 = 1 'auf 2. Kriterium ("33") prüfen  
    'zusätzlichen Teilstring nach einem Leerzeichen an die Zusatzzeile anfügen  
    If Left(Z, KLen) = Kenn3 Then Wert = Wert & " " & Mid(Z, P3Start, P3Len)  
Loop

'letzten Block verarbeiten  
If Krit1 * Krit2 = 1 Then 'wenn beide Kriterien erfüllt sind ...  
    '... Block schreiben und dabei Zusatz-Zeile für Platzhalter (lt Var "Mark") einsetzen ...  
    A.Write Replace(Block, Mark, vbNewline & Einf & Wert)
Else ' ... ansonsten ...  
    A.Write Replace(Block, Mark, "") '... Platzhalter vor dem Schreiben rückstandsfrei entfernen  
End If
Grüße
bastla
Member: Calim3ro
Calim3ro Jul 14, 2013 at 22:08:12 (UTC)
Goto Top
Hallo Dieter

Der Aufruf des VB-Skripts via cmd läuft super.

Besten Dank dafür.

Hallo bastla

Hmm, irgendwie werden die Information aus der 44er-Zeile Position 5-9 nicht hinter die 99er-Zeile mit der Information aus der 11er-Zeile geschrieben.

Liegt das daran, dass ich Skript-Zeile 49. Wert = Mid(Z, KLen +1) durch Wert = Mid(Z, 3, 6) ersetzt habe? Brauche aus der 11er-Zeile nur die Information der Position 3-6...

Falls ja, wie kann dies umgangen werden? Benötige aus der 11er-Zeile die Information der Positionen 3-6, welche hinter die 99er-Zeile geschriben wird. Dahinter die Information Position 5-9 der 44er-Zeile.

Falls zu kompliziert erklärt, kann ich auch eine Zeichnung erstellen. face-wink

Gruss Calim3ro
Mitglied: 76109
76109 Jul 14, 2013 updated at 23:07:52 (UTC)
Goto Top
Hallo Calim3ro!

Liegt das daran, dass ich Skript-Zeile 49. Wert = Mid(Z, KLen +1) durch Wert = Mid(Z, 3, 6) ersetzt habe? Brauche aus der 11er-Zeile nur die Information der Position 3-6...
Das spielt eigentlich keine Rolle, allerdings sind es von Position 3-6 nur 4 Zeichen und mit Mid(Z, 3, 6) liest Du aber 6 Zeichen ab Position 3. Der letzte Parameter steht für Anzahl...

Gruß Dieter
Member: Calim3ro
Calim3ro Jul 15, 2013 at 20:09:01 (UTC)
Goto Top
Hallo Dieter & bastla

Besten Dank für deine Anmerkung.
Die 6 Zeichen sind auch richtig. War schon etwas spät gestern, deswegen habe ich ein bischen den Durchblick verloren.
Aber nun klappt alles! Falls es noch weitere Anpassungen geben sollte, darf ich mich sicher nochmals an euch wenden. face-smile

Eine schöne Woche wünsch ich euch.

Gruss Calim3ro
Member: Calim3ro
Calim3ro Aug 14, 2013 at 11:55:31 (UTC)
Goto Top
Hallo zusammen

Hallo bastla

Ich mal wieder mit einem Anliegen zu diesem Skript.
Erst mal vorneweg, dieser funktioniert super, besten Dank nochmal.
Nun hat sich jedoch einiges geändert, was gewisse Anpassungen am Skript erforder und ich wieder auf Eure Hilfe angewiesen bin.

Wie muss dieses Skript angepasst werden, um die Information wie folgt zu verarbeiten:

Stand bisher:

11 AAAAAAA
22 BBBBBBB
33 CCCCCCC
44 DDDDDDD
55 EEEEEEE
99 AAAAAAA DDDD

Stand neu:

11 AAAAAAA
22 BBBBBBB
33 CCCCCCC
44 DDDDDDD
55 EEEEEEE
99 DDDD 050000 <----- Fortlaufende Nummer, welche bei 50'000 beginnt
11 AAAAAAA
22 BBBBBBB
33 CCCCCCC
44 DDDDDDD
55 EEEEEEE
99 DDDD 050001 <----- Fortlaufende Nummer

Information AAAAAAA soll in ein neu erstelltes File geschrieben werden, bei welcher die fortlaufende Nummer vorneweg steht:

050000 AAAAAAA
050001 AAAAAAB
etc...

Die fortlaufende Nummer wird nie über 999999 hinausgehen....

Besten Dank für Eure Bemühungen schonmal im Voraus.

Bei Unklarheiten bitte nachfragen.

Gruss Calim3ro
Member: bastla
bastla Aug 15, 2013 at 19:14:14 (UTC)
Goto Top
Hallo Calim3ro!

Ich hoffe, Dich richtig verstanden zu haben - falls ja, könnte das so gehen (wie immer ungetestet face-wink):
Kenn =    "11"  
Kenn2 =   "33"  
P2Start = 10
P2Ende =  15
Kenn3 =   "44"  
P3Start = 5
P3Ende =  9
Einf =    "99"  
NStart = 50000
Stellen = 6

With WScript.Arguments
    If .Count <> 4 Then
        WScript.Echo "Falsche Anzahl an Argumenten!"  
        WScript.Quit 1
    Else
        Ein =    .Item(0)
        Aus =    .Item(1)
        Liste =  .Item(2)
        AListe = .Item(3)
    End If
End With

Nummer = 10 ^ Stellen + NStart 'Startwert (um eine Zehnerpotenz größer als lt "Stellen" wegen der führenden Nullen) erzeugen  
KLen = Len(Kenn) 'Längen der Teilstrings vor der Schleife ...  
P2Len = P2Ende - P2Start + 1 '...  
P3Len = P3Ende - P3Start + 1 '... und damit nur einmal berechnen  

Mark = "§§§" 'Platzhalter für einzufügende Zeile; darf in der zu verarbeitenden Datei nicht enthalten sein  

Set fso = CreateObject("Scripting.FileSystemObject")  
Set E = fso.OpenTextFile(Ein)
Set A = fso.CreateTextFile(Aus)
Set AL = fso.CreateTextFile(AListe)

'Positivliste so in Variable einlesen, dass jeder Eintrag durch eine Zeilenschaltung begrenzt ist  
L = vbNewline & fso.OpenTextFile(Liste).ReadAll & vbNewLine 

Do While Not E.AtEndOfStream
    Z = E.ReadLine
    If Left(Z, KLen) = Kenn Then 'Blockbeginn?  
        If Krit1 * Krit2 = 1 Then 'wenn beide Kriterien erfüllt sind ...  
            '... Block schreiben und dabei Zusatz-Zeile für Platzhalter (lt Var "Mark") einsetzen ...  
            A.Write Replace(Block, Mark, vbNewline & Einf & Zusatz)
            'Zeile mit Nummer und Wert aus Zeile "Krit1" in Ausgabeliste schreiben  
            AL.WriteLine Right(Nummer, Stellen) & " " & Wert   
            Nummer = Nummer + 1 'Nummer weiterzählen  
        Else ' ... ansonsten ...  
            A.Write Replace(Block, Mark, "") '... Platzhalter vor dem Schreiben rückstandsfrei entfernen  
        End If
        If Wert <> "" Then 'ab zweitem Block ...  
            '... neuen Block mit Zeilenschaltung (vorhergehender Block endet ohne Zeilenschaltung) beginnen  
            Block = vbNewLine & Z & Mark
        Else
            Block = Z & Mark
        End If
        Wert = Mid(Z, KLen + 1)
        'Teilstring in "L" (Liste) suchen und Ergebnis als 0 oder 1 speichern  
        Krit1 = Sgn(InStr(L, vbNewline & Mid(Z, P2Start, P2Len) & vbNewline))
        Krit2 = 0 'Kriterium Kennung 2 rücksetzen  
    Else
        Block = Block & vbNewline & Z 'Zeile an Block mit Zeilenschaltung anfügen  
    End If
    If Left(Z, KLen) = Kenn2 Then Krit2 = 1 'auf 2. Kriterium ("33") prüfen  
    'zusätzlichen Teilstring nach einem Leerzeichen an die Zusatzzeile anfügen  
    If Left(Z, KLen) = Kenn3 Then Zusatz = Mid(Z, P3Start, P3Len) & " " & Right(Nummer, Stellen)  
Loop

'letzten Block verarbeiten  
If Krit1 * Krit2 = 1 Then 'wenn beide Kriterien erfüllt sind ...  
    '... Block schreiben und dabei Zusatz-Zeile für Platzhalter (lt Var "Mark") einsetzen ...  
    A.Write Replace(Block, Mark, vbNewline & Einf & Zusatz)
    'Zeile mit Nummer und Wert aus Zeile "Krit1" in Ausgabeliste schreiben  
    AL.WriteLine Right(Nummer, Stellen) & " " & Wert   
Else ' ... ansonsten ...  
    A.Write Replace(Block, Mark, "") '... Platzhalter vor dem Schreiben rückstandsfrei entfernen  
End If
Hinsichtlich der Zeile 57 (oben: 49) müsstest Du ggf wieder selbst die Anpassung an die richtige Position / Zeichenanzahl vornehmen.

Die Ausgabeliste ist beim Aufruf als zusätzlicher Parameter (siehe Zeile 20) zu übergeben.

Grüße
bastla
Member: Calim3ro
Calim3ro Aug 17, 2013 at 09:32:30 (UTC)
Goto Top
Hallo bastla

Besten Dank für Deine schnelle Antwort und Bemühung.

Natürlich wie immer ungetestet und wie immer funktionierts (nach ein paar kleinen Anpassungen) ausgezeichnet!

Gruss Calim3ro
Member: Calim3ro
Calim3ro Mar 14, 2014 at 17:39:55 (UTC)
Goto Top
Hallo zusammen

Hallo bastla

Es gibt wieder mal eine kleine Anpassung an diesem Script und ich hoffe, ihr könnt mir weiterhelfen.

Der String, welcher in die neue Datei geschrieben wird, sollte von einem vorhergehenden Zeichen (Q) befreit werden.

Stand bisher:

050000 QQQAAAA
050001 QQAAQAB

Stand neu:

050000 AAAA
050001 AAQAB

Es können also auch Q's im benötigten Teil vorkommen, welche erhalten bleiben müssen. Nur die führenden Q's sollten gelöscht werden.

Wie würde die Anpassung im obrigen Script aussehen?

Besten Dank für eure Bemühungen.

Bei Unklarheiten einfach nachfragen...

Es grüsst Calim3ro
Member: bastla
Solution bastla Mar 14, 2014, updated at Mar 17, 2014 at 21:28:34 (UTC)
Goto Top
Hallo Calim3ro!

Einmal mehr ohne Test meinerseits:
Kenn =    "11"  
Kenn2 =   "33"  
P2Start = 10
P2Ende =  15
Kenn3 =   "44"  
P3Start = 5
P3Ende =  9
Einf =    "99"  
Entf = "Q" 'zu entfernendes Zeichen am Beginn des Wertes für die Ausgabeliste  
NStart = 50000
Stellen = 6

With WScript.Arguments
    If .Count <> 4 Then
        WScript.Echo "Falsche Anzahl an Argumenten!"  
        WScript.Quit 1
    Else
        Ein =    .Item(0)
        Aus =    .Item(1)
        Liste =  .Item(2)
        AListe = .Item(3)
    End If
End With

Nummer = 10 ^ Stellen + NStart 'Startwert (um eine Zehnerpotenz größer als lt "Stellen" wegen der führenden Nullen) erzeugen  
KLen = Len(Kenn) 'Längen der Teilstrings vor der Schleife ...  
P2Len = P2Ende - P2Start + 1 '...  
P3Len = P3Ende - P3Start + 1 '... und damit nur einmal berechnen  

Mark = "§§§" 'Platzhalter für einzufügende Zeile; darf in der zu verarbeitenden Datei nicht enthalten sein  

Set fso = CreateObject("Scripting.FileSystemObject")  
Set E = fso.OpenTextFile(Ein)
Set A = fso.CreateTextFile(Aus)
Set AL = fso.CreateTextFile(AListe)

'Positivliste so in Variable einlesen, dass jeder Eintrag durch eine Zeilenschaltung begrenzt ist  
L = vbNewline & fso.OpenTextFile(Liste).ReadAll & vbNewLine 

Do While Not E.AtEndOfStream
    Z = E.ReadLine
    If Left(Z, KLen) = Kenn Then 'Blockbeginn?  
        If Krit1 * Krit2 = 1 Then 'wenn beide Kriterien erfüllt sind ...  
            '... Block schreiben und dabei Zusatz-Zeile für Platzhalter (lt Var "Mark") einsetzen ...  
            A.Write Replace(Block, Mark, vbNewline & Einf & Zusatz)
            'Zeile mit Nummer und Wert aus Zeile "Krit1" in Ausgabeliste schreiben  
            AL.WriteLine Right(Nummer, Stellen) & " " & Wert   
            Nummer = Nummer + 1 'Nummer weiterzählen  
        Else ' ... ansonsten ...  
            A.Write Replace(Block, Mark, "") '... Platzhalter vor dem Schreiben rückstandsfrei entfernen  
        End If
        If Wert <> "" Then 'ab zweitem Block ...  
            '... neuen Block mit Zeilenschaltung (vorhergehender Block endet ohne Zeilenschaltung) beginnen  
            Block = vbNewLine & Z & Mark
        Else
            Block = Z & Mark
        End If
        Wert = Mid(Z, KLen + 1) 'Wert auslesen  
        Do While Left(Wert, 1) = Entf 'Solange Wert mit Zeichen lt "Entf" beginnt ...  
            Wert = Mid(Wert, 2) '... erstes Zeichen von Wert abschneiden  
        Loop
        'Teilstring in "L" (Liste) suchen und Ergebnis als 0 oder 1 speichern  
        Krit1 = Sgn(InStr(L, vbNewline & Mid(Z, P2Start, P2Len) & vbNewline))
        Krit2 = 0 'Kriterium Kennung 2 rücksetzen  
    Else
        Block = Block & vbNewline & Z 'Zeile an Block mit Zeilenschaltung anfügen  
    End If
    If Left(Z, KLen) = Kenn2 Then Krit2 = 1 'auf 2. Kriterium ("33") prüfen  
    'zusätzlichen Teilstring nach einem Leerzeichen an die Zusatzzeile anfügen  
    If Left(Z, KLen) = Kenn3 Then Zusatz = Mid(Z, P3Start, P3Len) & " " & Right(Nummer, Stellen)  
Loop

'letzten Block verarbeiten  
If Krit1 * Krit2 = 1 Then 'wenn beide Kriterien erfüllt sind ...  
    '... Block schreiben und dabei Zusatz-Zeile für Platzhalter (lt Var "Mark") einsetzen ...  
    A.Write Replace(Block, Mark, vbNewline & Einf & Zusatz)
    'Zeile mit Nummer und Wert aus Zeile "Krit1" in Ausgabeliste schreiben  
    AL.WriteLine Right(Nummer, Stellen) & " " & Wert   
Else ' ... ansonsten ...  
    A.Write Replace(Block, Mark, "") '... Platzhalter vor dem Schreiben rückstandsfrei entfernen  
End If
Neu ist die Zeile 9 zum Festlegen des zu entfernenden Zeichens ("Q") und der Block in den Zeilen 59 - 61, in dem die führenden "Q" abgetrennt werden.

Grüße
bastla
Member: Calim3ro
Calim3ro Mar 17, 2014 at 11:33:26 (UTC)
Goto Top
Hallo bastla

Danke für Deine Rückmeldung.

Ich habe die Anpassungen gemäss deiner Vorlage in mein Script kopiert, jedoch wird der String "Wert" immen noch mit führenden "Q" ausgegeben...

Kann das daran liegen, dass ich den Wert nicht wie in deinem Script nicht mit Wert = Mid(Z, KLen + 1) definier habe, sondern mit Wert = Mid(Z, 3, 6) ?

Falls dies zu kompliziert ist (oder ich zu blöde) können die führenden "Q's" auch mit einem zweiten Script aus dem File entfernt werden. Der zu kürzende Wert befindet sich an der Position 9-13. Wie würde ein solcher Aussehen?

Besten Dank für Deine Hilfe.

Gruss Calimero
Member: bastla
Solution bastla Mar 17, 2014 updated at 21:28:23 (UTC)
Goto Top
Hallo Calim3ro!

Wie der Inhalt von "Wert" zustande kommt ist egal - nach der Schleife (Zeilen 59 - 61) müssten das/die zu entfernenden Zeichen (Variable "Entf", Zeile 9) jedenfalls weg sein ...

Nur zur Sicherheit: Vorausgesetzt habe ich, dass "Q" ein einzelnes Zeichen, bei dem zwischen Groß- und Kleinschreibung unterschieden wird, ist.

Grüße
bastla
Member: Calim3ro
Calim3ro Mar 17, 2014 at 21:28:18 (UTC)
Goto Top
Hallo bastla!

Habe beim meinem Script den Fehler gefunden und behoben.( bei Mid(Z, 3, 6) war 3 ein Leerzeichen....)

Nun tuts genau das, was ich wollte.

Besten Dank für deine Bemühungen!

Gruss Calimero
Member: Calim3ro
Calim3ro Jun 07, 2014 at 12:43:42 (UTC)
Goto Top
Hallo zusammen

Gerne würde ich (wieder einmal) eine Anpassung an diesem Skript machen.
Es sollen pro "Zeilenblock" die erste und letzte Zeile, welche auf Pos 1-7 ein numerischen Wert haben, anstelle von P3Start, P3Len geschrieben werden. Die Abfrage von Kenn3 gelöscht werden.

11 AAAAAAA
22 BBBBBBB
33 CCCCCCC
44 DDDDDDD
55 EEEEEEE
99 DDDD 050000
1234567 ----> Wert1
0000000
9876543 ----> Wert2
11 AAAAAAA
22 BBBBBBB
33 CCCCCCC
44 DDDDDDD
55 EEEEEEE
3456789 ----> Wert1
11111111
2222222
7654321 ----> Wert2
99 DDDD 050001

In diesem Beispiel muss der Wert1 und Wert2 übernommen werden, da diese die erste und letzte Zeile mit numerischen Werten im "Zeilenblock" sind.

Wie müsste die Anpassung am obrigen Skript aussehen?

Besten Dank für eure Hile im Voraus.

Grüsse Calimero