90957
Goto Top

Variable mit Leerzeichen auf eine bestimmte länge auffüllen. Oder alle Leerzeichen am ende löschen.

Hallo ihr Batcher,

Ich speichere verschiedene Daten in Zeilen einer Textdatei und lese Teile dieser Zeilen wieder aus.
Mehrere Daten in einer Zeile. Ich verwende das wie eine Datenbank
über Set "var1=%var1:~X,X%
Also die Var1 ist immer mit einer festen Zeichenanzahl gefüllt.
(Die Daten sind nicht immer gleich lang aber ich habe das einfach mit Leerzeichen
aufgefüllt, wenn zu wenig Zeichen vorhanden waren.)

Dann speichere ich die Version einer ExE in Var2.
(Die Var2 hat eine Variable Länge)
Jetzt will ich Var1 mit mit var2 vergleichen.
Ich denke das Problem liegt auf der Hand.

Jetzt würde ich gerne einfach mit möglichst kompaktem Code
entweder Var2 mit Leerzeichen auffüllen oder in Var1 alle
Leerzeichen am Ende löschen.

Ich würde mich über Antworten freuen,
und ich melde mich auch zurück!

Gruß
BluBb_mADe

PS:
Wenn man Ping>NUL verwendet wird dann eigendlich trotzdem der errorlevel gesetzt?
Und wenn nicht wie kann man ping mit errorlevel unsichtbar laufen lassen?

Content-Key: 144405

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

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

Member: bastla
bastla Jun 08, 2010 at 15:20:54 (UTC)
Goto Top
Hallo BluBb_mADe!

Gibt es die Leerzeichen in %var1% nur am Ende? In diesem Fall sollte eigentlich
for /f %%i in ("%var1%") do set "var1neu=%%i"
genügen ...

[Edit]
Alternativ dazu kannst Du auch mit "findstr" untersuchen, ob %var2% dem Beginn von %var1% entspricht:
echo %var1%|findstr /b /c:"%var2%">nul && echo %var2% entspricht dem Anfang von %var1%
[/Edit]

Grüße
bastla
Mitglied: 90957
90957 Jun 08, 2010 at 15:25:28 (UTC)
Goto Top
Nein eben nicht.

Die Variable beinhaltet überall Leerzeichen.
(Es sind nicht alle Zeichen Leerzeichen...)
Aber es dürfen nur die Leerzeichen am Ende gelöscht weden.

Das ist ja das große Problem!

Aber das mit Findstr könnte sogar funktionieren!
Da hab ich garnicht dran gedacht!
Das probier ich gleich aus.
Es besteht eben das Risiko das sich andere teile der Variablen gleichen,
die sind nämlich sehr ähnlich.
Danke!

Trotzdem noch mal ein kleiner schnipsel aus dem Code:
for /F "delims=" %%a in ('findstr /i /n / "%realm1var%" realmversion.bcl') do set n=%%a  
for /F "delims=:, tokens=1" %%a in ("%n%") do set n=%%a  
Set /a "cnt=1"  
for /F "Tokens=*" %%i in (realmversion.bcl) do call :bla %n% "%%i"  
set var=%var:~30,14%
goto hopsweiter
:bla
If %cnt%==%1 Set "Var=%~2"  
Set /a "cnt+=1"   
goto :eof
:hopsweiter
if not "%spielversion%"=="Version nicht erkannt!" (if "%spielversion%"=="%var%" (echo richtige Spielversion) else (color 0c  
echo falsche Spielversion))
Member: bastla
bastla Jun 08, 2010 at 15:36:13 (UTC)
Goto Top
Hallo BluBb-mADe!
Es besteht eben das Risiko das sich andere teile der Variablen gleichen,
die sind nämlich sehr ähnlich.
Deswegen ja auch "/b" ...

Grüße
bastla

P.S.: Dein P.S. von oben ist mir so nicht klar ...
Mitglied: 77559
77559 Jun 08, 2010 at 16:50:50 (UTC)
Goto Top
Hallo BluBb_mADe,

ich würde den Trim Befehl mit einem Call realisieren:
@Echo off
Setlocal
Set "Var=Text    mit    Leerstellen    "  an   "   irgendwelchen         Positionen"  
Set "Var2=%Var:~12,48%"  

Echo "%Var2%"  
Call :Trim %Var2%
Echo "%Trim%"  
Goto :Eof

:Trim
set "Trim=%*"  
Goto :eof

Gruß
LotPings

PS: Die Ausgabeumleitung auf NUL hat auf den Errorlevel keine Einfluß.
Mitglied: 90957
90957 Jun 09, 2010 at 08:30:35 (UTC)
Goto Top
Vielen Dank LotPings,
Ich glaube das ist das was ich gesucht habe ...
Wieso funktioniert das?
Geht das auch ohne call?
(Wahrscheinlich nicht ...)
Das Script ist jetzt nämlich schon 25 Kb groß und voller
Einsprungpunkte ... und bei jedem neuen hab ich Sorge,
dass ich einen vergessen hab^^.

@bastla:
Was heißt den Beginn überprüfen?
Wie viele Zeichen überprüft er dann?
Wann gelten die beiden Strings als gleich?

Ich verwende findstr eigentlich nur um Zeilen in
einem Textdokument zu finden von mehr mit findstr versteh ich nicht...

Tut mir leid wegen der ganzen fragerei...

Gruß
BluBb_mADe

PS: Danke das wollte ich wissen...
Member: bastla
bastla Jun 09, 2010 at 09:00:19 (UTC)
Goto Top
Hallo BluBb_mADe!
Was heißt den Beginn überprüfen?
ab dem ersten Zeichen
Wie viele Zeichen überprüft er dann?
so viele Zeichen, wie %var2% enthält
Wann gelten die beiden Strings als gleich?
wenn alle Zeichen von %var2% ab dem ersten Zeichen von %var1% enthalten sind

Da Du nur von Leerzeichen am Ende des Strings geschrieben hattest, sollten die beiden im folgenden Beispiel verwendeten Strings als gleich angesehen werden, da %var2% zur Gänze am Anfang von %var1% steht (wobei allerdings alle Zeichen, also nicht nur Leerzeichen, um die %var1% länger ist als %var2%, ignoriert werden):
@echo off & setlocal
set "var1=Text    mit    Leerstellen      an     irgendwelchen         Positionen        "  
set "var2=Text    mit    Leerstellen      an     irgendwelchen         Positionen"  
echo %var1%|findstr /b /c:"%var2%">nul && echo "%var2%" entspricht (dem Anfang von) "%var1%"  
Grüße
bastla
Mitglied: 77559
77559 Jun 09, 2010 at 09:47:12 (UTC)
Goto Top
Zitat von @90957:
Ich glaube das ist das was ich gesucht habe ...
Wieso funktioniert das?
Die Cmd hat wohl eine interne Funktion die überflüssige Zeichen am Anfang/Ende der Parameterliste abschneidet.
%* gibt alle (bereinigten) Parameter zurück, selbst wenn man inzwischen mit shift einzelne Parameter "durchgeschoben" hat.

Geht das auch ohne call? (Wahrscheinlich nicht ...)
Du hast es erkannt face-wink

Das Script ist jetzt nämlich schon 25 Kb groß und voller Einsprungpunkte ...
und bei jedem neuen hab ich Sorge, dass ich einen vergessen hab.
Dagegen hilft nur systematisches Vorgehen,
hinter jedem Label kannst du ja eine Erläuterung anfügen und ich fülle das meist mit Strichen, Sternen etc auf.

Wenn du dann eine Referenz haben willst, mach dir eine Liste mit Zeilennummern.
findstr /i /n "^:[a-z]" Batchdatei.cmd

Gruß
LotPings.
Mitglied: 90957
90957 Jun 09, 2010 at 10:04:17 (UTC)
Goto Top
Verdammt,
jetzt habe ich 2 Lösungsmöglichkeiten.

Vielen vielen Dank an euch beide, dass ihr euch so eine Mühe gemacht habt!

Ich hab schon beides probiert und beides geht perfekt!
Jetzt hab ich ganz schön was gelernt!

Viele Grüße
BluBb_mADe
Member: Biber
Biber Jun 09, 2010 at 16:14:08 (UTC)
Goto Top
Moin BluBb_mADe, bastla & LotPings,

bastla hat ja mit seiner Lösung schon demonstriert, dass es manchmal viel sinnvoller sein kann , die eigentliche Fragestellung nicht allzu wortwörtlich zu nehmen.

Falls aber doch noch mal jemand -aus welchen Gründen auch immer- an einer Batch-RTrim()-Variante ohne Call :Sub-Routine knobelt...

--> Geht auch... Alles geht im Batch (außer Brotschneiden)...
:: ---- RTrimMitFOR_L.cmd
@echo off & SetLocal EnableDelayedExpansion
set "var1=blabla blubb blubb blablabla     "  
echo Var1:[%var1%]
FOR /L %%i in (100,-1,1) do If "!Var1:~-%%i,1!" gtr "" if "!Var1:~-%%i,1!" gtr " " (set /a "cut=%%i-1")  
echo Var1 getrimt: [!Var1:~0,-%cut%!]
Beispielaufruf am CMD-Prompt & Output:
>e:\schnipsel\RTrimMitFOR_L.cmd

Var1:[blabla blubb blubb blablabla     ]
Var1 getrimt: [blabla blubb blubb blablabla]

[ Variante wurde mir zugemailt, ist nicht von mir]

Grüße
Biber
Member: bastla
bastla Jun 09, 2010 at 16:44:50 (UTC)
Goto Top
Hallo @all!

Es ginge natürlich zur Not auch so:
:: ---- RTrimMitOhneFORundDelayedExpansion.cmd
@echo off & setlocal
set "var1=blabla blubb blubb blablabla     "  
echo Var1:[%var1%]
:Loop
if "%var1:~-1,1%"==" " (set "var1=%var1:~,-1%" & goto :Loop)  
echo Var1 getrimt: [%var1%]
Grüße
bastla
Member: Biber
Biber Jun 09, 2010 at 17:03:19 (UTC)
Goto Top
*lach*
@bastla,

Genau das war (fast buststabengetreu) die erste Alternative zu LotPings Ansatz,... gestern beim Brainstorming über diesen Thread:
[Zitat von Ansatz1, gestern ca 17:30h)
@echo off & setlocal enabledelayedexpansion
set "var1=blabla blubb blubb blablabla     "  
@echo [%var1%]
:loop
if "!var1:~-1,1!"==" " (set "var1=!var1:~0,-1!" & goto loop)  
@echo [%var1%]
goto :eof
[/Zitat Ansatz1]

Danach hatte ich versucht, statt mit ":loop" und "Goto :loop" alles mit einer FOR/L-Anweisung abzufackeln und war so weit gekommen:

@echo off & setlocal enabledelayedexpansion
set "var1=blabla blubb blubb blablabla     "  
@echo Var1:[%var1%]
FOR /L %%i in (1,1,100) do @If "!Var1:~-%%i,1!" gtr " " (set /a "cut=%%i-1"  & goto breakLoop)  
:breakLoop
echo [!Var1:~0,-%cut%!]

... weil ich irgendwie nicht über das Detailproblem "Variable %cut% muss um 1 gemindert werden" hinwegkam ohne wieder mit Sprungmarken zu agieren.

Die Variante "Mit FOR/L und DelayedExpansion ohne Sprungmarke" hat also bis heute nachmittag zum Reifen gebraucht...

Grüße
Biber
Member: bastla
bastla Jun 09, 2010 at 21:13:01 (UTC)
Goto Top
@Biber
Warum willst Du eigentlich das "goto" vermeiden (noch dazu auf Kosten einer "DelayedExpansion"?

Grüße
bastla
Member: Biber
Biber Jun 10, 2010 at 06:28:13 (UTC)
Goto Top
Moin bastla,

Zitat von @bastla:
@Biber
Warum willst Du eigentlich das "goto" vermeiden (noch dazu auf Kosten einer "DelayedExpansion"?

Neben der rein sportlichen Herausforderung ("Mal schauen, ob das geht....") sind es natürlich die üblichen Gründe
1) Ein "goto :Label" ist vielleicht nostalgisch, vielleicht schnell gemacht.... aber sorry, es ist kein Indiz für Codequalität.
Wenn wir hier ein paar Algorithmen vorkaspern wollen und auch wenn es einige Werkzeuge gibt, die ein "goto :irgendwohin" erlauben.... so etwas gehört schlicht und einfach verboten.
Ist nicht lesbar, nicht nachvollziehbar, nicht strukturiert.... einfach bäh.

2) Von daher war es bei mir natürlich auch ein Stück weit ein Reflex - unter anderem hier im Unternehmen sind "goto-Anweisungen" technisch möglich,
aber eigentlich nicht zulässig [Anmerkung: Ich rede hier nicht von CMD-Batch-Programmierung!]
Und ich muss SEHR oft mit Entwicklern diskutieren, ob denn eine im Code XY vorhandene "goto-Anweisung" wirklich nötig ist und wie es sich anders lösen liesse.

3) Der dritte Grund ist ... es macht einfach Spass, einen Teil der vielen Wege zu zeigen, die nach Rom führen.
Wie arm wäre das denn, einfach zu sagen "goto :rom" ?

Grüße
Biber
Mitglied: 77559
77559 Jun 10, 2010 at 07:02:59 (UTC)
Goto Top
Hallo Biber,

2) und 3) stimme ich zu.
Bei 1) nur eingeschränkt, da Batch nun mal keine do.until .Loop , do While..loop kennt finde ich deren Nachbildung mit Hilfe eines in direkter Nachbarschaft liegenden Goto :Label durchaus legitim.
In VB[A|S] z.Bsp. sähe ich das aber auch anders.

Gruß
LotPings
Member: bastla
bastla Jun 10, 2010 at 08:04:07 (UTC)
Goto Top
Hallo Biber und LotPings!
... finde ich deren Nachbildung mit Hilfe eines in direkter Nachbarschaft liegenden Goto :Label durchaus legitim.
entspricht auch ziemlich genau meiner Sichtweise.

Ist nicht lesbar, nicht nachvollziehbar ...
Den Wert 100 (obwohl unkommentiert face-wink) in
FOR /L %%i in (100,-1,1) do ...
kann ich zwar durch durchaus nachvollziehen, aber als Musterbeispiel für Eleganz würde ich diese Halbzeile auch nicht gerade heranziehen ...

All in all stellt wohl LotPings Ansatz den gelungensten Kompromiss dar. face-smile

Grüße
bastla
Member: Biber
Biber Jun 10, 2010 at 08:52:47 (UTC)
Goto Top
Okay, okay, bastla und Lotpings,

in diesen harten Zeiten, in denen wir alle Opfer bringen müssen, und sogar die CSU auf die Aufstellung eines eigenen Bundespräsidentenkandidaten verzichtet
da brauchen wir uns ja nicht unnötig hineinsteigern in die "Richtlinien Strukturierter Batchprogrammierung mit Cmd.exe".

Aber der gelungenste Ansatz ist IMHO nicht der vom Lord mit "Call :YellowSubmarine", sondern der klassich-stringente [bastla schreibt am 09.06.2010, 18:44:50 Uhr ]

Wenn überhaupt, dann ist der lesbar & wartbar und für weitere Verwendung in Gebrauchs-Bätchen zu empfehlen.

Meine Variante bitte ich als neckische Anekdote zu betrachten, so wie ich es auch gemeint habe.
Und ja... die "100" in meiner Halbzeile sind zwar relativ unauffällig untergejubelt, aber in der Tat nicht elegant. face-wink

Grüße
Biber