fomermay
Goto Top

Textdatei mit Sonderzeichen Zeilenweise auslesen, Zeilen bearbeiten und in neue Textdatei schreiben

Hallo,

folgendes Problem ich habe eine Textdatei mit einer beliebigen Anzahl an Zeilen, die alle eine unterschiedliche Länge haben. Ich will jede Zeile auslesen, die Anzahl der Zeichen ermitteln, die Zeile mit Leerzeichen auffüllen und danach die Zeile in eine neue Textdatei schreiben. Das bekomme ich prinzinpiell hin, sobald aber ein Sonderzeichen (&) in der Zeile vorhanden ist wird diese übersprungen.
@ECHO OFF & setlocal enabledelayedexpansion

:START
SET /A num=0
SET pfad=C:\

IF EXIST %pfad%Datei_neu.txt DEL %pfad%Datei_neu.txt

REM Ermittlung der Gesamtanzahl an Zeilen
FOR /F "delims=:" %%A IN ('findstr /N .* "%pfad%Datei_alt.txt"') DO SET zeilenGesamt=%%A  

REM Schleife, die jede Zeile der Zieldatei öffent und an Sprungmarke :AUSLESEN übergibt
FOR /F "delims=" %%A IN (%pfad%Datei_alt.txt) DO CALL :auslesen "%%A"  
REM Wenn alle Zeilen durchlaufen gehe zu Sprungmarke :EOF
GOTO :EOF

REM Wird für jede Zeile der Zieldatei aufgerufen, gibt die Zeilennummer an, weisst
REM die Zeile einer fortlaufenden Variable zu und übergibt diese an die Sprungmarke
REM strLaeng
:auslesen
SET /A num=%num%+1
ECHO Zeile %num% von %zeilenGesamt% Zeilen
SET var%num%="%~1"  
GOTO :strLaeng %var%num%%

REM Bestimmen der Anzahl Zeichen pro Zeile
:strLaeng
SET WorkString=%*
SET strLength=0
REM Es wird jedes Zeichen einer Zeile durchgegangen bis kein Zeichen mehr vorhanden ist,
REM beim jedem Durchlauf wird die Varibale strLength eins hochgezählt.
:strLaeBe
IF NOT "!WorkString:~%strLength%,1!"=="" (  
  SET /A strLength += 1
  GOTO :strLaeBe
)
REM Die Variable der neuen Zeile wird erzeugt.
SET neueZeile=%*
SET neueZeile=%neueZeile:~1,-1%
REM Es wird die Anzahl der Zeichen ermittelt welche an den neuen String angehängt werden müssen.
SET /A strNeu=1555-%strLength%
SET strSpace= 
REM Für die Anzahl der fehlenden Zeichen wird die Sprungmarke :Leerstel aufgerufen
FOR /L %%a IN (1,1,%strNeu%) DO CALL :leerstel
SET neueZeile3=%neueZeile:~0,1555%
ECHO %neueZeile%>>%pfad%Datei_neu.txt

GOTO :EOF

REM Der neuen Zeile wird bei jedem Durchlauf ein Leerzeichen angefügt.
:leerstel
SET neueZeile=%neueZeile%%strSpace%

GOTO :EOF
Mit diesem Code wurden auch die Zeilen mit Sonderzeichen übernommen, mein Problem liegt jetzt darin das in dieser Zeile
SET neueZeile=%neueZeile:~1,-1%
also beim entfernen der "" die Meldung bringt:
"Der Befehl "Mi" ist entweder falsch geschrieben oder konnte nicht gefunden werden."

"Mi" sind die Zeichenkette die hinter dem Sonderzeichen "&" kommen, und alle was hinter dem "&" wird nicht in die Neue Datei geschrieben. Lasse ich die Zeile weg werden natürlich nicht die Sonderzeichen entfernt, später kann ich sie nicht entfernen weil ich da ja schon die Leerzeichen hinten auffülle und das hintere Leerzeichen nicht mehr das letzte Zeichen ist.

ich hoffe ihr könnt mir helfen.

Content-ID: 178156

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

Ausgedruckt am: 22.11.2024 um 04:11 Uhr

bastla
bastla 28.12.2011 um 21:05:14 Uhr
Goto Top
Hallo FomerMay und willkommen im Forum!

Abgesehen vom "Maskieren" der Sonderzeichen durch ein vorangestelltes "^" und einer auf die reine Ausgabe beschränkten Verwendung von "delayedexpansion" (wird auch im unten gezeigten Ansatz eingesetzt) für das Lösen des "Sonderzeichen-Problems" stellt sich die Frage, wozu die ganze Zeichenzählerei gut sein soll; wenn es nur darum ginge, alle Zeilen durch das Anfügen von Leerzeichen auf eine Länge von 1555 Zeichen zu bringen, würde ich einfach etwas in der Art verwenden:
@ECHO OFF & setlocal
SET Pfad=C:\
set "Ein=Datei_alt.txt"  
set "Aus=Datei_neu.txt"  
set /a Len=1555

set "Spaces="  
setlocal enabledelayedexpansion
for /L %%i in (1,1,%Len%) do set "Spaces=!Spaces! "  
endlocal & set "Spaces=%Spaces%"  

IF EXIST "%Pfad%%Aus%" DEL "%Pfad%%Aus%"  
FOR /F "tokens=1* delims=:" %%a IN ('findstr /n "^" "%Pfad%%Ein%"') DO set "Zeile=%%b" & CALL :ausgeben  
REM Wenn alle Zeilen durchlaufen sind, gehe zu Sprungmarke :EOF (= beende den Batch)
GOTO :EOF

REM Wird für jede Zeile der Zieldatei aufgerufen und gibt die Zeile mit einer Gesamtlänge von 1555 Zeichen aus
:ausgeben
set "neueZeile=%Zeile%%Spaces%"  
setlocal enabledelayedexpansion
>>"%Pfad%%Aus%" echo(!neueZeile:~,%Len%!  
endlocal
GOTO :EOF
Es wird hier einfach vorweg ein String von 1555 Leerzeichen erzeugt, dann dieser an jede einzelne Zeile angefügt und jeweils die ersten 1555 Zeichen der so entstandenen neuen Zeile ausgegeben.

Soferne keine Leerzeilen zu berücksichtigen sind (wie es Dein oben stehender Code vermuten lässt), ließe sich die Zeile 13 auch auf
FOR /F "usebackq delims=" %%a IN ("%Pfad%%Ein%") DO set "Zeile=%%a" & CALL :ausgeben
reduzieren.

Grüße
bastla
FomerMay
FomerMay 28.12.2011 um 21:45:35 Uhr
Goto Top
Das ist natürlich ein viel eleganterer Weg das Problem zu lösen, danke für die Hilfe bei meinen Code aber auch danke für den Denkanstoß!
rubberman
rubberman 28.12.2011 um 21:48:22 Uhr
Goto Top
Hallo Zusammen,

auch hier nochmal die etwas andere Lösung via SET /P

@echo off &setlocal
set "Pfad=C:\"  
set "Ein=Datei_alt.txt"  
set "Aus=Datei_neu.txt"  
set /a Len=1555

setlocal EnableDelayedExpansion
set "Spaces="  
for /l %%i in (1,1,%Len%) do set "Spaces=!Spaces! "  
<"%Pfad%%Ein%" >"%Pfad%%Aus%" (  
  for /f %%n in ('type "%Pfad%%Ein%"^|find /c /v ""') do for /l %%i in (1 1 %%n) do (  
    set "Zeile="  
    set /p "Zeile="  
    set "Zeile=!Zeile!%Spaces%"  
    set "Zeile=!Zeile:~,%Len%!"  
    echo(!Zeile!
  )
)

Grüße
rubberman

<EDIT auch wenns nun schon gelöst ist face-wink />
FomerMay
FomerMay 29.12.2011 um 09:12:26 Uhr
Goto Top
Auch danke an rubberman face-smile

Es hat geklappt (sowohl die Erweiterung für meinen Code als auch die Beispiele von bastla und rubberman), ich hätte jetzt nur noch eine kleine Frage zu bastla's Code

SET "neueZeile=%Zeile%%Spaces%"  
setlocal enabledelayedexpansion
>>"%Pfad%%Aus%" echo(!neueZeile:~,%Len%!  
endlocal

Wo liegt der Unterschiede ziwschen
>>"%Pfad%%Aus%" echo(!neueZeile:~,%Len%!  
und
echo(!neueZeile:~,%Len%!)>>"%Pfad%%Aus%"  
bastla
bastla 29.12.2011, aktualisiert am 18.10.2012 um 18:49:28 Uhr
Goto Top
Hallo FomerMay!
Wo liegt der Unterschied
Deine Zeile (und damit auch die Ausgabe) enthält eine schließende Klammer ...

Die Schreibweise mit der öffnenden Klammer (hier von jeb-the-batcher empfohlen) ist ein Ersatz für "echo." oder "echo\" oder einige weitere mögliche Varianten, welche alle den Sinn haben, eine Leerzeile - und nicht im Fall des Falles
ECHO ist eingeschaltet (ON).
- zu erzeugen (wäre hier zwar nicht erforderlich, aber schadet auch nicht).

Grüße
bastla
Biber
Biber 29.12.2011 um 12:42:33 Uhr
Goto Top
Moin FomerMay,

willkommen im Forum auch von mir.

Die von bastla verwendete Schreibweise hat mehrere Vorteile.

Zum einen hilft es, unbeabsichtige Nebeneffekte zu vermeiden, wenn der rausgeECHOte String mit einer Ziffer endet.
In diesem Fall [also "Ziffer-Umleitungsanweissung-Umleitungsziel" z.B. "echo test 1>logfile.txt") würde eine Fehlinterpretation erfolgen.
Der CMD-Interpreter würde es "lesen" als "Mach mir ein Echo test" und leite alles auf Ausgabekanal 1 erscheinende um in logfie.txt"

Statt "test 1" würde also nur "test" in der Logdatei ankommen

Hauptgrund ist aber die Les- und Wartbarkeit von Schnipseln.

Vergleiche einfach dieses Beispiel:

...
echo Hier lege ich meine neue Logdatei an>%Pfad%%Aus%
echo Nu hänge ich einen mittellangen Text an, weil es dann nicht so langweilig zu lesen ist.>>%Pfad%%Aus%

REM Zwischendurch irgendwelche Aufgaben des Schnipsels...

echo Und noch einen kurzen Text am Ende>>%Pfad%%Aus%
Dasselbe in anderer Schreibweise

...
 >%Pfad%%Aus% echo Hier lege ich meine neue Logdatei an
>>%Pfad%%Aus% echo Nu hänge ich einen mittellangen Text an, weil es dann nicht so langweilig zu lesen ist.

REM Zwischendurch irgendwelche Aufgaben des Schnipsels...

>>%Pfad%%Aus% echo Und noch einen kurzen Text am Ende

Die zweite Variante ist einfach leichter zu lesen und zu pflegen..

Grüße
Biber