offline
Goto Top

leerzeichen am anfang und ende einer batch Variablen entfernen (trim in php)

Hallo Leute,

ich würde gerne aus einer Variable die fürhrenden leerzeichen und die am ende entfernen falls vorhanden.
Die Anzahl der leerstellen ist unbekannt, und die leerstellen zwischen worten müssen bleiben.

%var1 =" das ist eine variabel "

ergebnis ="das ist eine variabel"

hat jemand eine idee?

vbs oder andere skripts will ich nicht umbedingt einsetzen.

Danke schonmal

Content-Key: 77687

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

Printed on: April 20, 2024 at 03:04 o'clock

Member: bastla
bastla Jan 09, 2008 at 16:58:48 (UTC)
Goto Top
Hallo OFFLINE!

Genau genommen sind die Leerzeichen in Deinem Beispiel keine führenden Leerzeichen, da sich davor ein Anführungszeichen befindet (in Batch werden Strings grundsätzlich nicht in Anführungszeichen eingeschlossen).

Beispiel mit "echten" führenden Leerzeichen:
@echo off & setlocal
set "var1=   das ist eine variable     "  
echo Vorher:  #%var1%#

:loop1
if "%var1:~0,1%"==" " set "var1=%var1:~1%" & goto :loop1  
:loop2
if "%var1:~-1%"==" " set "var1=%var1:~0,-1%" & goto :loop2  

echo Nachher: #%var1%#
Sollte der Inhalt der Variablen aber tatsächlich die beschriebenen Anführungszeichen enthalten, dann so:
@echo off & setlocal
set var1=" das ist eine variabel "  
echo Vorher:  %var1%
for /f "delims=" %%i in (%var1%) do set "var1=%%~i"  

:loop1
if "%var1:~0,1%"==" " set "var1=%var1:~1%" & goto :loop1  
:loop2
if "%var1:~-1%"==" " set "var1=%var1:~0,-1%" & goto :loop2  

set var1="%var1%"  
echo Nachher: %var1%

Grüße
bastla
Member: OFFLINE
OFFLINE Jan 10, 2008 at 11:38:51 (UTC)
Goto Top
Hallo bastla

dein skript funktioniert einwandfrei, Danke vielmals.
ich habe die erste variante gewählt, da keine "" vorkommen.

Allerdings habe ich noch ein kleines Problem mit dem Einbinden:

FOR /F "eol=# tokens=1-12 delims=;" %%a IN (imptest.csv) DO (  
        echo #%%d#
        :loop1
        if "%%d:~0,1%"==" " set "d=%%d:~1%" & goto :loop1  
        :loop2
        if "%%d:~-1%"==" " set "d=%%d:~0,-1%" & goto :loop2  
        echo #%%d#
)

Ich bekomme beim Ausführen Syntaxfehler. Leider kann ich es mir nicht erklären warum.
Danke für die Hilfe
Member: bastla
bastla Jan 10, 2008 at 14:21:40 (UTC)
Goto Top
Hallo OFFLINE!

Die Zerlegung in Teilstrings lässt sich auf die Laufvariablen von "for"-Schleifen nicht anwenden, daher musst Du den gelesenen Wert zunächst einer anderen Variablen zuweisen.

Je nachdem, ob Du ausschließen kannst, dass die zu verarbeitenden Daten das Zeichen "!" enthalten, gibt es zwei mögliche Vorgangsweisen: die Verwendung eines Unterprogrammes oder die "delayedexpansion", die "verzögerte Variablenauflösung". Für letztere gilt die oben angeführte Einschränkung auf Variablenwerte ohne "!".

Mit Unterprogramm würde es dann so aussehen:
@echo off & setlocal
FOR /F "eol=# tokens=1-12 delims=;" %%a IN (imptest.csv) DO call :ProcessLine "%%~d"  
goto :eof

:ProcessLine
set "valtemp=%~1"  
echo #%valtemp%#

:loop1
if "%valtemp:~0,1%"==" " set "valtemp=%valtemp:~1%" & goto :loop1  
:loop2
if "%valtemp:~-1%"==" " set "valtemp=%valtemp:~0,-1%" & goto :loop2  

echo #%valtemp%#
goto :eof
Einige Anmerkungen:

Sollten die aus der CSV-Datei ausgelesenen Werte in Anführungszeichen eingeschlossen sein, werden diese durch die Schreibweise %%~d entfernt. Da der Wert an das Unterprogramm (entspricht einem externen, eigenständigen Batch) weitergegeben werden soll, wird er neuerlich zwischen Anführungszeichen gesetzt (um ev "Binnen"-Leerzeichen zu erhalten und den vollständigen Wert weiterzugeben). Durch diese Vorgangsweise wird sichergestellt, dass, unabhängig von der Darstellung der Ausgangsdaten mit oder ohne Anführungszeichen, die Übergabe mit Anführungszeichen erfolgt.

Im Unterprogramm kommt dieser Parameter als %1 an und wird (durch %~1 von den umgebenden Anführungszeichen "befreit") in die Variable %valtemp% "umgespeichert, da auch mit den Parametervariablen %0 bis %9 die Stringzerlegung nicht durchgeführt werden kann.

Noch kurz zu "goto :eof": Damit wird das Ende eines Programmteiles signalisiert, was für das Hauptprogramm "Ende Batch" bedeutet, während es im Unterprogramm als "Return" interpretiert wird. Soferne nach dem Unterprogramm keine weiteren Batchzeilen folgen, kannst Du es auch weglassen - der Rücksprung erfolgt dennoch.

Sollte übrigens %%d tatsächlich ein Wert ohne enthaltene Leerzeichen sein, würde auch schon
@echo off & setlocal
FOR /F "eol=# tokens=1-12 delims=;" %%a IN (imptest.csv) DO call :ProcessLine %%~d  
goto :eof

:ProcessLine
echo #%1#
goto :eof
genügen, da bei der Parameterübergabe die Leerzeichen als Trennzeichen gelten und damit weg fallen.

Grüße
bastla
Member: OFFLINE
OFFLINE Jan 10, 2008 at 17:36:50 (UTC)
Goto Top
Hallo bastla,

danke vielmals für deine bemühungen, ich hätte nicht gedacht, dass es so aufwendig ist, so etwas zu realisieren. Leider funktioniert das obere Skript nur bedingt, da es auch gelegentlich werte gibt, die leer sind. in der CVS-Datei sind sie dann nicht leer, sondern werden durch eine unbestimmte anzahl leertasten dargestellt.
wenn ich mir die schleifendurchläufe ansehe, sehe ich, dass bei jedem durchlauf der wert um ein leerzeichen verkürzt wird. Nach dem letzten Leerzeichen kommt ein Syntaxfehler.

man muss also noch abfangen, falls die variablen nur leertasten enthalten....

ich hoffe das ist nicht zuviel verlangt.
Member: bastla
bastla Jan 10, 2008 at 22:13:20 (UTC)
Goto Top
Hallo OFFLINE!

Unter der Voraussetzung, dass die Trennzeichen (";") bei leeren Werten nicht unmittelbar aufeinander folgen, sondern dazwischen mindestens 1 Leerzeichen steht, sollte es genügen, nach ":loop1" folgende Zeile einzufügen:
if not defined valtemp goto :NoValue
und nach der (bisher) letzten Zeile die Fehlerbehandlung für diesen Fall durchzuführen - Beispiel:
:NoValue
echo Es wurde kein Wert gefunden!
goto :eof
Sollten allerdings zwei ";" unmittelbar aufeinander folgen, werden diese als nur ein Trennzeichen interpretiert und es wird dann der Wert des nächsten nicht leeren Feldes verwendet - sag Bescheid, falls das bei Dir zutreffen sollte.

Grüße
bastla
Member: OFFLINE
OFFLINE Jan 14, 2008 at 23:23:00 (UTC)
Goto Top
Hallo bastla,
übers wochenende bin ich nicht dazu gekommen mir deinen vorschlag anzusehen.
heute hab ich mich dann mal drangewagt. funktioniert auch bestens.

allerdings habe ich etwas anderes bemerkt:
kann es sein, dass die for-schleife den string in nur maximal 9 tokens cutten kann?
bei allen datensätzen funktioniert die batch bei den letzten 3 werten nicht. in den variablen steht dann der wert der ersten variabel mit einer angehängten laufenden nummer. Bsp:
Aus:
  48810;   8; 13;MARTIN MEIER, SPIELWAREN   ;INH. MARTIN MEIER     ;35339  ;MARWALD       ;HAFFOELLERSTR. 198       ;INFO@SPIELWAREN.DE  ;07421/9737-0   ;07421/973735   ;  6;  
wird:
#48810#
#8#
#13#
#MARTIN MEIER, SPIELWAREN#
#INH. MARTIN MEIER#
#35339#
#MARWALD#
#HAFFOELLERSTR. 198#
#INFO@SPIELWAREN.DE#
#488100#
#488101#
#488102#

ich kann es mir leider nicht ganz erklären...

wenn die for-schleife nur 9 werte übergeben kann, brauche ich eine andere lösung.

Danke schonmals.
Member: bastla
bastla Jan 14, 2008, updated at Oct 18, 2012 at 16:35:18 (UTC)
Goto Top
Hallo OFFLINE!

Besteht das Problem nach Berücksichtigung von csv-Datei per Batch in einzelne variablen zerlegen immer noch?

Falls ja, bitte Deinen Code posten ...

Grüße
bastla
Member: OFFLINE
OFFLINE Jan 14, 2008 at 23:36:49 (UTC)
Goto Top
hier mein code (in stark vereinfachter form):


import.bat
@echo off 
setlocal

FOR /F "eol=# tokens=1-12 delims=;" %%a IN (imptest.csv) DO call :ProcessLine "%%~a" "%%~b" "%%~c" "%%~d" "%%~e" "%%~f" "%%~g" "%%~h" "%%~i" "%%~j" "%%~k" "%%~l"   

:ProcessLine
echo %~1
echo %~2
echo %~3
echo %~4
echo %~5
echo %~6
echo %~7
echo %~8
echo %~9
echo %~10
echo %~11
echo %~12

imptest.csv
   1520;   2;  1;DRESCHEL                       ;INH. H. DRESCHEL               ;91745  ;HEMKLOR                       ;STAEDER STR. 21                ;                                         ;<07771/123223177>   ;FAX 07771/23791235 ;  6;  
Member: bastla
bastla Jan 14, 2008, updated at Oct 18, 2012 at 16:35:18 (UTC)
Goto Top
Hallo OFFLINE!

In diesem Fall muss ich auf csv-Datei per Batch in einzelne variablen zerlegen und den von miniversum verwendeten "shift"-Befehl verweisen, da tatsächlich bei %9 (oder %~9) Schluss ist.

Brauchst Du denn alle 12 Felder? Falls doch nicht, könntest Du ja die Buchstaben der nicht benötigten Felder nach "call :ProcessLine" weglassen ...

Grüße
bastla
Member: OFFLINE
OFFLINE Jan 14, 2008 at 23:56:32 (UTC)
Goto Top
Hallo bastla,

ja ich brauche alle 12 face-wink
mit dem shift befehl funktioniert es allerdings. Hatte ich in der eile bei miniversum übersehen.
musste nur gerade feststellen, dass > und < in der csv nicht funktionieren.
aber ich denke dafür mache ich einen neuen thread auf, falls ich nichts finden sollte was aus der csv alle < und > entfernt. Hm am besten wäre es wohl alle "" >< und / \ zu entfernen, um möglichst allen problemen aus dem weg zu gehen.

danke vielmals für die Hilfe
Member: bastla
bastla Jan 15, 2008 at 00:24:11 (UTC)
Goto Top
Hallo OFFLINE!

Als Zwischenschritt:
@echo off
setlocal

FOR /F "eol=# delims=" %%z IN (imptest.csv) DO set "Zeile=%%~z" & call :ProcessLine  
goto :eof

:ProcessLine
set "Zeile=%Zeile:"=%"  
set "Zeile=%Zeile:<=%"  
set "Zeile=%Zeile:>=%"  
for /f "tokens=1-12 delims=;" %%a in ("%Zeile%") do (  
	set "var1=%%~a"  
	set "var2=%%~b"  
	set "var3=%%~c"  
	set "var4=%%~d"  
	set "var5=%%~e"  
	set "var6=%%~f"  
	set "var7=%%~g"  
	set "var8=%%~h"  
	set "var9=%%~i"  
	set "var10=%%~j"  
	set "var11=%%~k"  
	set "var12=%%~l"  
)
echo %var1% %var2% %var3% %var4% %var5% %var6% %var7% %var8% %var9% %var10% %var11% %var12%

Grüße
bastla

P.S.: Und Du bist ganz sicher, dass es Batch sein soll, und nicht vielleicht VBS?
Member: bastla
bastla Jan 15, 2008 at 00:46:30 (UTC)
Goto Top
... und so schon näher am Ergebnis:
@echo off
setlocal

FOR /F "eol=# delims=" %%z IN (imptest.csv) DO set "Zeile=%%~z" & call :ProcessLine  
goto :eof

:ProcessLine
::Sonderzeichen entfernen
set "Zeile=%Zeile:"=%"  
set "Zeile=%Zeile:<=%"  
set "Zeile=%Zeile:>=%"  

::Leerzeichen entfernen
:loop
set "ZeileAlt=%Zeile%"  
set "Zeile=%Zeile: ;=;%"  
set "Zeile=%Zeile:; =;%"  
if "%Zeile:~0,1%"==" " set "Zeile=%Zeile:~1%"  
if "%Zeile:~-1%"==" " set "Zeile=%Zeile:~0,-1%"  
if "%Zeile%" neq "%ZeileAlt%" goto :loop  

::Leere Felder durch "_" kennzeichnen (wegen Reihenfolge bei der Zerlegung) 
:loop2
set "ZeileAlt=%Zeile%"  
set "Zeile=%Zeile:;;=;_;%"  
if "%Zeile%" neq "%ZeileAlt%" goto :loop2  

for /f "tokens=1-12 delims=;" %%a in ("%Zeile%") do (  
	set "var1=%%~a"  
	set "var2=%%~b"  
	set "var3=%%~c"  
	set "var4=%%~d"  
	set "var5=%%~e"  
	set "var6=%%~f"  
	set "var7=%%~g"  
	set "var8=%%~h"  
	set "var9=%%~i"  
	set "var10=%%~j"  
	set "var11=%%~k"  
	set "var12=%%~l"  
)
echo #%var1%#  #%var2%#  #%var3%#  #%var4%#  #%var5%#  #%var6%#  #%var7%#  #%var8%#  #%var9%#  #%var10%#  #%var11%#  #%var12%#

Grüße
bastla
Member: OFFLINE
OFFLINE Jan 15, 2008 at 10:53:40 (UTC)
Goto Top
hallo bastla,
dir scheint das ja richtig spass zu machen den leuten hier mit ihren problemen zu helfen face-smile

ich bin mir mittlerweile nicht mehr so sicher, ob ein vbs nicht vielleicht besser wäre. ich hätte nicht gedacht, dass es so aufwändig ist, eine csv einzulesen und in einzelne werte zu zerteilen.
ich werde mal geschwind alles zusammenbauen und dann hier posten. vielleicht hat jemand dann doch eine bessere idee.

MfG
Member: bastla
bastla Jan 15, 2008 at 12:03:52 (UTC)
Goto Top
Hallo OFFLINE!

dir scheint das ja richtig spass zu machen den leuten hier mit ihren problemen zu helfen face-smile
Wie kommst Du denn auf die Idee? face-wink

ich werde mal geschwind alles zusammenbauen und dann hier posten.
Gute Strategie, falls damit gemeint ist, dass Du die weiteren Verarbeitungsschritte (bzw das eigentliche Ziel der Aktion) beschreiben willst ...

Grüße
bastla
Member: OFFLINE
OFFLINE Jan 16, 2008 at 13:21:23 (UTC)
Goto Top
so ich habe hier mal den gesamten code. ist doch mehr geworden als ich dachte.
im grunde will ich einen csv export komplett umformatieren um per csvde in ad einlesen zu können. dieser vorgang wird 1x alle 24h durchgeführt.

@echo off 
setlocal
del temp.csv
del temp2.csv
del neuecsv.csv
echo DN,objectClass,displayName,sn,streetAddress,postalCode,l,mail,
telephoneNumber,facsimile TelephoneNumber,extensionAttribute1,
extensionAttribute2,extensionAttribute3,extensionAttribute12 >> neuecsv.csv

FOR /F "delims=|" %%x IN (EXKD002.csv) DO echo %%x >> temp.csv  
more +1 temp.csv > temp2.csv
dsrm "OU=ordner2,OU=ordner1,OU=Kontakte,DC=domain,DC=de" -subtree -exclude -noprompt  
FOR /F "eol=# delims=" %%z IN (temp2.csv) DO set "Zeile=%%~z" & call :ProcessLine1  
goto :eof

:ProcessLine1
set "Zeile=%Zeile:"=%"  
set "Zeile=%Zeile:,=%"  
set "Zeile=%Zeile:<=%"  
set "Zeile=%Zeile:>=%"  

FOR /F "eol=# tokens=1-12 delims=;" %%a IN ("%Zeile%") DO call :ProcessLine2 "%%~a" "%%~b" "%%~c"  
 "%%~d" "%%~e" "%%~f" "%%~g" "%%~h" "%%~i" "%%~j" "%%~k" "%%~l"   
goto :eof

:ProcessLine2
	set "sp1=%~1"  
	set "sp2=%~2"  
	set "sp3=%~3"  
	set "sp4=%~4"  
	set "sp5=%~5"  
	set "sp6=%~6"  
	set "sp7=%~7"  
	set "sp8=%~8"  
	set "sp9=%~9"  
	shift
	set "sp10=%~9"  
	shift
	set "sp11=%~9"  
	shift
	set "sp12=%~9"  
	
	:loop1
	if not defined sp1 goto :sp1NoValue
	if "%sp1:~0,1%"==" " set "sp1=%sp1:~1%" & goto :loop1  
        :loop2
        if "%sp1:~-1%"==" " set "sp1=%sp1:~0,-1%" & goto :loop2  
	:sp1NoValue
	:loop3
	if not defined sp2 goto :sp2NoValue
	if "%sp2:~0,1%"==" " set "sp2=%sp2:~1%" & goto :loop3  
	:loop4
	if "%sp2:~-1%"==" " set "sp2=%sp2:~0,-1%" & goto :loop4  
	:sp2NoValue
	:loop5
	if not defined sp3 goto :sp3NoValue
	if "%sp3:~0,1%"==" " set "sp3=%sp3:~1%" & goto :loop5  
	:loop6
	if "%sp3:~-1%"==" " set "sp3=%sp3:~0,-1%" & goto :loop6  
	:sp3NoValue
	:loop7
	if not defined sp4 goto :sp4NoValue
	if "%sp4:~0,1%"==" " set "sp4=%sp4:~1%" & goto :loop7  
	:loop8
	if "%sp4:~-1%"==" " set "sp4=%sp4:~0,-1%" & goto :loop8  
	:sp4NoValue
	:loop9
	if not defined sp5 goto :sp5NoValue
	if "%sp5:~0,1%"==" " set "sp5=%sp5:~1%" & goto :loop9  
	:loop10
	if "%sp5:~-1%"==" " set "sp5=%sp5:~0,-1%" & goto :loop10  
	:sp5NoValue
	:loop11
	if not defined sp6 goto :sp6NoValue
	if "%sp6:~0,1%"==" " set "sp6=%sp6:~1%" & goto :loop11  
	:loop12
	if "%sp6:~-1%"==" " set "sp6=%sp6:~0,-1%" & goto :loop12  
	:sp6NoValue
	:loop13
	if not defined sp7 goto :sp7NoValue
	if "%sp7:~0,1%"==" " set "sp7=%sp7:~1%" & goto :loop12  
	:loop14
	if "%sp7:~-1%"==" " set "sp7=%sp7:~0,-1%" & goto :loop14  
	:sp7NoValue
	:loop15
	if not defined sp8 goto :sp8NoValue
	if "%sp8:~0,1%"==" " set "sp8=%sp8:~1%" & goto :loop15  
	:loop16
	if "%sp8:~-1%"==" " set "sp8=%sp8:~0,-1%" & goto :loop16  
	:sp8NoValue
	:loop17
	if not defined sp9 goto :sp9NoValue
	if "%sp9:~0,1%"==" " set "sp9=%sp9:~1%" & goto :loop17  
	:loop18
	if "%sp9:~-1%"==" " set "sp9=%sp9:~0,-1%" & goto :loop18  
	:sp9NoValue
	:loop19
	if not defined sp10 goto :sp10NoValue
	if "%sp10:~0,1%"==" " set "sp10=%sp10:~1%" & goto :loop19  
	:loop20
	if "%sp10:~-1%"==" " set "sp10=%sp10:~0,-1%" & goto :loop20  
	:sp10NoValue
	:loop21
	if not defined sp11 goto :sp11NoValue
	if "%sp11:~0,1%"==" " set "sp11=%sp11:~1%" & goto :loop21  
	:loop22
	if "%sp11:~-1%"==" " set "sp11=%sp11:~0,-1%" & goto :loop22  
	:sp11NoValue
	:loop23	
	if not defined sp12 goto :sp12NoValue
	if "%sp12:~0,1%"==" " set "sp12=%sp12:~1%" & goto :loop23  
	:loop24
	if "%sp12:~-1%"==" " set "sp12=%sp12:~0,-1%" & goto :loop24          
	:sp12NoValue

	echo "CN=%sp4%,OU=ordner2,OU=ordner1,OU=Kontakte,DC=domain,DC=de",contact,"%sp4%",  
"%Sp5%","%sp8%","%sp6%","%sp7%","%sp9%","%sp10%","%sp11%","%sp1%","%sp2%",  
"%sp3%","%sp12%" >> neuecsv.csv  

ein problem bleibt allerdings noch übrig:
in der letzten Zeile füge ich die werte in einer datei in der richtigen reihenfolge mit "%spx%" wieder zusammen (sp steht für spalte).
wenn eine spalte leer ist, dann steht ,"", in der datei. beim import nimmt er das dann nicht an. er erwartet bei leeren feldern ,, Ich benötige die "" aber, da es werte mit leerzeichen gibt.
ich habe ja die :spxNoValue für jede variable sobald diese leer ist. wie kann ich jetzt die letzte echo zeile verändern, dass wenn eine var keinen wert hat die "" nicht in die datei kommen?

DANKE,DANKE,DANKE für die super geniale Hilfe.
Member: bastla
bastla Jan 16, 2008 at 13:39:40 (UTC)
Goto Top
Hallo OFFLINE!

wie kann ich jetzt die letzte echo zeile verändern, dass wenn eine var keinen wert hat die "" nicht in die datei kommen?
Bist Du sicher, dass die Anführungszeichen beim Import benötigt werden (denn für die "echo"-Zeile sind sie eigentlich nicht erforderlich)?

Ansonsten fiele mir folgender Workaround ein: Da jedes Feld (außer dem letzten) ein anschließendes "," benötigt, könntest Du dieses einfach dem Feldinhalt hinzufügen. Wenn ein Feld leer ist ("if not defined"), erhält es eben als einzigen Inhalt ein Komma. Natürlich müssten dann auch die erforderlichen Anführungszeichen bereits Feldinhalt werden [Edit] Unnötiger Schnellschuss ... [/Edit]

Besser (einfacher): Wo benötigt (bzw für alle nicht leeren Felder), die Anführungszeichen in das Feld aufnehmen. [Edit] Siehe unten [/Edit]

Grüße
bastla

[Edit] Idee für Workaround genauer formuliert. [/Edit]
Member: OFFLINE
OFFLINE Jan 16, 2008 at 13:43:01 (UTC)
Goto Top
ich benotige die anführungszeichen für das programm csvde, beim import.

wenn ein wert eine leertaste hat kommt ein fehler wenn keine ""

geht: "das ist ein test","bla","blubb",,,"bä"
geht nicht: das ist ein test,bla,blubb,,,bä
geht nicht:"das ist ein test","bla","blubb","","","bä"
Member: bastla
bastla Jan 16, 2008 at 13:52:08 (UTC)
Goto Top
Hallo OFFLINE!

Dann am besten in der Art:
	:loop1
	if not defined sp1 goto :sp1NoValue
	if "%sp1:~0,1%"==" " set "sp1=%sp1:~1%" & goto :loop1  
	set sp1="%sp1%"  

Grüße
bastla