batzjunior
Goto Top

Batchdatei: Leerzeichen in File schreiben/Zeilenumbruch verhindern

Hallo @ alle,

ich habe die "tolle" Aufgabe, ein XML-File in ein ASCII-File mit festen Feldlängen zu überführen. Ein wenig bin ich schon vorangekommen, hänge jetzt allerdings an einer Sache:

Da die Felder vorgeschriebene Feldlängen haben, muss der Platz, den der entsprechende Wert nicht einnimmt mit Leerzeichen aufgefüllt werden. Ich dachte, ich könnte das so lösen:


::errorlänge=Länge der Zeichenkette
::laenge=Feldlänge

...

:write
set /a errorlevel+=1
::---hinter dem zweiten %zeichenfolge% ist noch ein Leerzeichen-----
set %zeichenfolge%=%zeichenfolge%
if not %errorlevel%==%laenge% goto :write
echo %zeichenfolge%>>daten.txt

Leider wird aber kein Leerzeichen hinzugefügt... Hat jmd. eine Idee, wie man das erreichen kann?

Anderes Problem: Nach jedem umgeleiteten Echo in eine Datei wird ein Zeilenumbruch eingefügt. Die Daten sollen jedoch hintereinander auf einer Zeile stehen. Gibt es eine Möglichkeit, den Zeilenumbruch zu verhindern?

Vielen Dank und viele vorweihnachtliche Grüße

Daniel

Content-Key: 46838

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

Printed on: April 24, 2024 at 22:04 o'clock

Member: AxelHahn
AxelHahn Dec 15, 2006 at 14:14:53 (UTC)
Goto Top
Hi Daniel

Füge das Sonderzeichen ^ und ein Leerzeichen ein. Beim SET nimm bei der zu setzenden Variable die % Zeichen weg:

set zeichenfolge=^ %zeichenfolge%

... dann geht es.

Viele Grüsse
-= Axel =-
Member: BatzJunior
BatzJunior Dec 15, 2006 at 14:29:48 (UTC)
Goto Top
Hi Axel,

vielen Dank, dass hat super geklappt! Weißt Du zufällig auch noch eine Lösung für das Zeilenumbruch-Problem?

Liebe Grüße!

Daniel
Member: AxelHahn
AxelHahn Dec 15, 2006 at 14:43:10 (UTC)
Goto Top
Hi Daniel,

bei jedem

echo [irgendwas] >>%ausgabefile%

wird eine einzelne Zeile geschreiben. Ich wüsste lediglich die Variante, dass du die Zeile in einer Variable zusammenbaust und am Ende die Sammelvariable mit echo schreibst, also so etwa:

set ausgabefile=%temp%\testfile.txt
set line=
set line=%line% Hallo
set line=%line% Welt
echo %line% >>%ausgabefile%

Viele Grüsse
-= Axel =-
Member: Biber
Biber Dec 15, 2006 at 23:11:53 (UTC)
Goto Top
Moin BatzJunior und AxelHahn,

auch wenn ja schon eine Lösung gefunden ist, noch zwei Anmerkungen von mir.

a) das (bewusste) Anfügen von leading oder trailing blanks wie auch das Vermeiden von versehentlichen Leerzeichen habe ich mir wie folgt angewöhnt:
>set "text1=bla" & set "text2=blubb   "  & set "text3=        nochwas"  
>echo text1[%text1%] text2[%text2%] text3[%text3%]
text1[bla] text2[blubb   ] text3[        nochwas]

b) Dementprechend würde ich auch das Auffüllen auf eine bestimmte Festlänge anders machen.

@echo off & setlocal enableDelayedExpansion
Set "40spaces=                                        "  

....(XMLDatei durchflöhen, Tags zuordnen...
...
If /i [%TagName%]==[KUNDENNAME] call :writeFeld "%TagValue%" 20  
If /i [%TagName%]==[KUNDENR]        call :writeFeld "%TagValue%" 12 Left  
....
goto :eof

:writeFeld Parameter1 %einwert% Parameter2=SollLänge opt.Parameter3=Links auffüllen
if [%3]== (
   REM nicht links auffüllen -- also [%einwert% + SPACES] 
   Set "thisvalue=~%1%40spaces%"  
) Else (
   Set "thisvalue=%40spaces%%~1"  
   REM links auffüllen -- also [SPACES + %einwert%] 
)
if [%3]== (
   REM nicht links auffüllen -- also  n Zeichen von links gezählt
   set thisvalue=!thisvalue:~0, %2!
) Else (
     REM links auffüllen -- also  n Zeichen von rechts gesehen
    set thisvalue=!thisvalue:~-%2!
)
REM .... lieber nicht: echo %thisvalue%>>daten.txt  
REM ..ich würde es auch "sammeln", wie AxelHahn gepostet hat  
Set "GanzerDatensatz=%GanzerDatensatz%%thisvalue%"  
goto :eof

Gruß
Biber
Member: BatzJunior
BatzJunior Dec 18, 2006 at 09:08:59 (UTC)
Goto Top
Hey Biber,

vielen Dank für Deine Antwort, die mich schon ein ganzes Stückchen weitergebracht hat! Auch möchte ich mich für Deine Tutorials, aus denen ich so einiges mitnehmen konnte, bedanken!
Ein Problem habe ich jetzt noch: Und zwar beihalten die Tagwerte zum Teil Anführungszeichen. Wie kann ich es anstellen, diese da herauszubekommen bzw. zu maskieren?

set wert2=%wert2:"=^"%

funktioniert da nicht und bei einigen Überprüfungen streikt die Konsole, wenn an einer bestimmten Stelle gerade ein Anführungszeichen vorkommt...

Liebe Grüße; Daniel
Member: miniversum
miniversum Dec 18, 2006 at 10:15:20 (UTC)
Goto Top
versuchs so:

set wert2=%~wert2%

oder alternativ:

set wert2=%wert2:~1,-1%

miniversum
Member: BatzJunior
BatzJunior Dec 18, 2006 at 12:47:32 (UTC)
Goto Top
Vielen Dank!
Member: Biber
Biber Dec 18, 2006 at 13:38:09 (UTC)
Goto Top
Moin BatzJunior,

teilen wir uns die Restarbeit?
Du setzt auf "Gelöst", ich verschiebe den Beitrag von "Entwicklung" nach "Batch & Shell" und schließe ihn demnächst?

Ich gehe schon mal in Vorleistungen und verschiebe den Thread...

[Wenn noch Fragen offen sind, dann natürlich weiterfragen...]

Gruß
Biber
Member: BatzJunior
BatzJunior Dec 19, 2006 at 07:40:25 (UTC)
Goto Top
Hi Biber und alle anderen,

eine Frage habe ich tatsächlich noch:
Da die Feldlängen ja fest vorgegeben sind, die Längen der Werte ja aber variieren, muss ich für jeden Wert die Länge ermitteln. Zum Glück habe ich dazu ein nettes Batch-Programm im Netz gefunden, welches seine Aufgabe auch (fast) perfekt bewerkstelligt. Das Problem dabei ist jedoch das es seeeehr langsam arbeitet. Somit brauche ich für einen XML-File mit ca. 60 Werten 3 Minuten...
1. Siehst Du/seht ihr im folgenden Code des Programmes noch irgendwelche Verbesserungsmöglichkeiten hinsichtlich der Performance oder muss ich mich mit einem langsamen Programm abfinden?

::setlocal
set errorlevel=-1
if {%1}=={} echo NO ARG GIVEN&call :Help &goto :endit
if {%1}=={/?} call :Help &goto :endit
:start
if {%1}=={} goto :goodendit
set /a paramnum=0
set /a totpos=0
set instring=%1
set instring=%instring:"=%
call :GET_LENGTH %instring%
:goodendit
set /a spaces=%paramnum%-1
set /a totpos=%totpos%+%spaces%
set errorlevel=%totpos%
:endit
::echo %errorlevel%
::endlocal
goto :eof

:GET_LENGTH
:NEXT_STRING
if {%1}=={} goto :eof
set /a paramnum+=1
set string=%1
set /a pos=0
:NEXT_CHAR
set onechar=%%string^:^~%pos%,1%%
for /f "tokens=1,2 delims==" %%a in ('set onechar') do for /f %%c in ('echo %%b') do call :countit %%c
if defined GOTADDED goto :NEXT_CHAR
set /a totpos=%totpos%+%pos%
shift /1
goto :NEXT_STRING

:Help
echo USAGE:%~n0 string OR %~n0 "see with spaces"
echo function returns the length of the string or -1 (error)
echo a string with embedded spaces should be in quotes ex."count letters"
echo in a batch NTscript "for /f %%%%A in ('length STRING') do set var=%%%%A"
set errorlevel=
goto :eof

:countit
set GOTADDED=
if /i {%1}=={echo} goto :eof
set /a pos+=1
set GOTADDED=yes
goto :eof

Vielen Dank an alle!

Daniel
Member: Biber
Biber Dec 19, 2006 at 20:30:19 (UTC)
Goto Top
Na ja, BatzJunior,

sagen wir so: ein bisschen die Luft aus dem Käse drücken könnten wir schon...

Fangen wir langsam an.
Wenn ich die Länge eines Strings, beispielsweise die Länge meiner Variablen %path% wissen wollte, würde ich am CMD-Prompt eintippseln:
>(@echo %path%>x) & @for %i in (x) do @set /a "%~zi-2" & del x  
672
...und 672 wäre auch die Länge von meinem %path%.
Okay, weil ich nicht so oft aufräume natürlich.

Wenn du so etwas als Call-baren Block :GetLen brauchst, hier eine kleine Demo:
::----------snipp GetStringlenDemo.bat
@echo off & Setlocal & Set "@=%temp%\strlen.tmp"  
::--Begin DEMOSTUFF
Set "EinSatz=seht ihr im folgenden Code des Programmes noch irgendwelche "Verbesserungsmöglichkeiten" hinsichtlich der Performance oder muss ich mich mit einem langsamen Programm abfinden?"  
Set "M$="Sympathischer Weltmarktführer""  
(Echo 1.Demo Länge vom String [%M$%] ermitteln:) & call :getLen %M$% && echo --- 
(Echo 2.Demo Länge vom String [%EinSatz%] ermitteln:)
For /f "tokens=1,*" %%i in ("%Einsatz%") do call:GetAllLen %%i %%j  
del %@% & goto :eof
 
:GetAllLen
call:Getlen %1
If [%2]== goto :eof
shift & Goto GetAllLen
::--End DEMOSTUFF  
:getlen
(echo.%1>%@%) & for %%i in (%@%) do @set /a strlen=%%~zi-2
@echo Länge von [%1] ist [%strlen%]
::----------snipp GetStringlenDemo.bat

Demo der Demo:
(=21:16:54  D:\temp=)
>f:\administrator\GetStringLenDemo.bat
1.Demo Länge vom String ["Sympathischer Weltmarktführer"] ermitteln:  
Länge von ["Sympathischer Weltmarktführer"] ist [31]  
---
2.Demo Länge vom String [seht ihr im folgenden Code des Programmes noch irgendwelche "Verbesserungs  
öglichkeiten" hinsichtlich der Performance oder muss ich mich mit einem langsamen Programm abfinden  
] ermitteln:
Länge von [seht] ist [4]
Länge von [ihr] ist [3]
Länge von [im] ist [2]
Länge von [folgenden] ist [9]
Länge von [Code] ist [4]
Länge von [des] ist [3]
Länge von [Programmes] ist [10]
Länge von [noch] ist [4]
Länge von [irgendwelche] ist [12]
Länge von ["Verbesserungsmöglichkeiten"] ist [28]  
Länge von [hinsichtlich] ist [12]
Länge von [der] ist [3]
Länge von [Performance] ist [11]
Länge von [oder] ist [4]
Länge von [muss] ist [4]
Länge von [ich] ist [3]
Länge von [mich] ist [4]
Länge von [mit] ist [3]
Länge von [einem] ist [5]
Länge von [langsamen] ist [9]
Länge von [Programm] ist [8]
Länge von [abfinden?] ist [9]

(=21:16:55  D:\temp=)

Ich habe die bei meinem Prompt angezeigte Uhrzeit mit gepastet/gepostet.
Dauert also nicht soooooooooo lange.

HTH
Biber

P.S. Ich habe auch Strings mit "embedded spaces" berücksichtigt
P.P.S. Ein String der Länge 0 würde die Länge 0 haben statt -1 bei Dir.
P.P.P.S. Meinst Du, wir bekommen noch einen grünen Haken dran vor Silvester?
Member: Biber
Biber Dec 20, 2006 at 16:10:53 (UTC)
Goto Top
Moin BatzJunior,

danke für das Haken-Setzen.
Ich setze meinerseits diesen Thread jetzt auf "Geschlossen" - wir sehen uns ja ohnehin im nächsten Thread face-wink

Gruß
Biber