pieh-ejdsch
Goto Top

HowTo For Schleife mit TokenTrenner AnführungsZeichen ( double quotes as Delimiter )

Wie heisen die Dinger noch gleich? - doppelte Hochkommata; Gänsefüsschen oder doppelte Anführungszeichen.
Es gibt sicher noch ein paar Varianten dieses Zeichen " zu benennen.

Moin Admins,

Die AnführungsZeichen innerhalb einer Variable "Zeichen"Kette" mussten Vorerst mit dem Befehl Set separiert werden.
set "Variable=%Variable:"=%"

In Anlehnung an das Tutorial zur For Schleife
Für den Inhalt von Dateien macht sich aber der Tokentrenner delims= in der For-Schleife etwas einfacher.
Das AnführungsZeichen in einer Forschleife lässt sich mithilfe des Caret (Zirkumflex) Escapen als delimiter einsetzen.
Paradoxerweise müssen dafür um die Optionen der For /f - Schleife die doppelten Anführungszeichen weggelassen werden.

In der BefehlszeilenReferenz For geht es um Analyseschlüsselwörter.
Ich Verwende den Begriff Optionen wie im For Tutorial und in der CMD-Hilfe Help For
FOR /F "Optionen" %Variable IN (Ausdruck) DO Befehl [Parameter]

Bei einer Regulären Forschleife werden die AnführungsZeichen um die Optionen gesetzt, welche wiederum nur Notwendig sind, weil im For-Befehl Sonderzeichen enthalten sind.
Das Gleichheitszeichen = ist schon der erste Grund dafür.
Dieser Umstand macht die Nutzung des Caret zur Maskierung (als Escape-Funtion) des Nächsten Zeichens unmöglich.

Sehen wir nun erstmal was für SonderZeichen eine Sonderbehandlung benötigen.
In der CMD Hilfe CMD /? ist eine SonderZeichenbehandlung angegeben.
Die folgenden Sonderzeichen erfordern Anführungszeichen:

     <Leerzeichen>
     (){}^=;!'+,`~
nicht zu vergessen sind auch Befehls- und Verkettungszeichen
& > < |
und zuletzt nicht Auszulassen das doppelte AnführungsZeichen
     "
Da jetzt die AnführungsZeichen um die Optionen fehlen müssen diese SonderZeichen "Escaped" werden.
FOR /F Optionen %Variable IN (Ausdruck) DO Befehl [Parameter]

Beispiele am Promt
>for /f usebackq %i in ("D:\Help\abc.txt") do @echo %i
diese
dieser
"
diese"Zeile"ist"mit"AnfuerungsZeichen"zwischen"Den"Worten

>for /f usebackq^ delims^= %i in ("D:\Help\abc.txt") do @echo %i
diese Zeile enthaelt kein AnfuerungsZeichen
dieser Text enthaelt hier ->" ein Anfuerungszeichen
" dieser Text beginnt mit einem AnfuerungsZeichen
diese"Zeile"ist"mit"AnfuerungsZeichen"zwischen"Den"Worten

>for /f usebackq^ delims^=^" %i in ("D:\Help\abc.txt") do @echo %i
diese Zeile enthaelt kein AnfuerungsZeichen
dieser Text enthaelt hier ->
 dieser Text beginnt mit einem AnfuerungsZeichen
diese

>for /f eol^=^"^ usebackq^ delims^= %i in ("D:\Help\abc.txt") do @echo %i
diese Zeile enthaelt kein AnfuerungsZeichen
dieser Text enthaelt hier ->" ein Anfuerungszeichen
diese"Zeile"ist"mit"AnfuerungsZeichen"zwischen"Den"Worten

>for /f usebackq^ delims^=^"^ tokens^=1-8 %i in ("D:\Help\abc.txt") do @echo %i-%j-%k-%l-%m-%n-%o-%p
diese Zeile enthaelt kein AnfuerungsZeichen-------
dieser Text enthaelt hier ->- ein Anfuerungszeichen------
 dieser Text beginnt mit einem AnfuerungsZeichen-------
diese-Zeile-ist-mit-AnfuerungsZeichen-zwischen-Den-Worten

Mir ist bewusst, dass die Option delims im täglichen Umgang mit Forschleifen als letztes in den Optionen aufgeführt wird.
Die Frage nach dem "Warum Normal zuletzt" ist leicht beantwortet:

Das Leerzeichen und auch der Tab wird eh nur in den Delimiter aufgenommen wenn delims als letztes in den Optionen auftaucht.
Nur das Leerzeichen muss als letzter Delimeter angegeben werden.
Wenn delims dann NICHT als letztes in den Optionen genommen wird möchte man Kein LeerZeichen oder TAB als Trenner haben.

so werden Beide Varianten gleich Funktionieren
>for /f delims^=^"^	^ ^ ^ tokens^=2 %i in ("aa"bb "cc dd") do @echo :%i:
:bb :

>for /f tokens^=2delims^=^" %i in ("aa"bb "cc dd") do @echo :%i:
:bb :


für Variablen mit einer ungeraden Anzahl von AnführungsZeichen empfiehlt es sich immer die Verzögerte Auflösung der Variable zu Verwenden
in einer Batch
@echo off&setlocal

set "Test=abc " 1 ! 2 " def ^" ghi"  
setlocal enabledelayedexpansion
echo Test voll: !Test!

for /f eol^=^"^ delims^=^"^!^ tokens^=2^,3-4 %%i in ("!Test!") do endlocal & echo\Test aus der For: %%i.%%j.%%k  

pause
die Ausgabe der CMD
Test voll: abc " 1 ! 2 " def ^" ghi
Test aus der For:  1 . 2 . def ^
Drücken Sie eine beliebige Taste . . . _

Dazu möchte ich noch sagen, das eine in ProzentZeichen Angezeigte Variable mit enthaltenen SonderZeichen und enthaltenen Anführungszeichen die BefehlsZeile komplett Durcheinanderbringen kann.
@echo off&setlocal

set "Test=abc 	" 1 ! 2 "	 def ^" ghi"  
echo Test voll: %Test%

for /f eol^=^"^ delims^=^"^!^ tokens^=2^,3-4 %%i in ("%Test%") do endlocal & echo\Test aus der For: %%i.%%j.%%k  
pause

[Edit]
leicht Überarbeitet - hoffe nicht zu lang geworden
[/Edit]


Gruß Phil

Content-ID: 172844

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

Ausgedruckt am: 24.11.2024 um 04:11 Uhr

dog
dog 08.09.2011 um 22:15:11 Uhr
Goto Top
Delimiter as the double quotes

Trennzeichen als die doppelten Anführungszeichen

face-wink
pieh-ejdsch
pieh-ejdsch 08.09.2011 um 22:34:05 Uhr
Goto Top
Ok danke, habs umgedreht. Nicht das ich den Preis für die Unverständlichste Überschrift bekomme
99045
99045 08.09.2011 um 23:43:34 Uhr
Goto Top
Wie heisen die Dinger noch gleich? - doppelte Hochkommata; Gänsefüsschen oder doppelte Anführungszeichen.
Es gibt sicher noch ein paar Varianten dieses Zeichen " zu benennen.

http://de.wikipedia.org/wiki/Satzzeichen
http://www.duden.de/rechtschreibregeln/anfuehrungszeichen
pieh-ejdsch
pieh-ejdsch 09.09.2011 um 00:23:12 Uhr
Goto Top
Ja ich weis - in dem Sinne ist es kein Satzzeichen, sondern Korrekterweise ist es nur ein "Zollzeichen".
Zitat aus Wiki
Im Schreibmaschinensatz gibt es für öffnendes und schließendes Anführungszeichen nur ein Zeichen ("), das zugleich als Ersatzzeichen für Zoll, Sekunden oder Bogensekunden dient.

Da aber in der Hilfe für For Ausszug
    %~I         - Expandiert %I und entfernt alle umschließenden
                   Anführungszeichen (").
und generell in der CMD Hilfe es sich immer in Verbindung mit den ZollZeichen um die sogenannten AnführungsZeichen handelt, denke ich mal es genügt die Dinger Anführungszeichen zu nennen.

[Edit]
Aber für die Nutzbarkeit als delimiter ist es nicht hinreichend.
Aber es ist Nutzbar wie ein Beliebiger anderer Delimiter. Sonst wäre eine Nutzung jedes Anderen Delimters genauso Fraglich.
Ob eine Serparation mit einer Forschleife Sinn macht kommt auf die Ausgangssituation an.

Weil.... du bekommst auch keine anderen, wenn du im Laden nach einfachen handelsüblichen Anführungszeichen fragst.
darum hatte ich dies mit dem Vorsatz: doppelt nur eindeutiger Formulieren wollen - genau wie es auch dort steht - im Win 7 Help for
 usebackq        - Gibt an, dass die neue Semantik in Kraft ist,
                   wobei eine Zeichenfolge in umgekehrten Anführungs-
                   zeichen als Befehl ausgeführt wird und eine
                   Zeichenfolge in Anführungszeichen ein literaler
                   Befehl ist, der die Verwendung von doppelten
                   Anführungszeichen um Dateinamen in Dateien-
                   sätzen erlaubt.
wogegen in XP so darüber geplänkelt wird
usebackq 	Gibt an, dass Sie bei der Angabe von Dateinamen in Dateinamensatz Anführungszeichen 
		verwenden können; eine Zeichenfolge in schrägen, einzelnen Anführungszeichen wird als 
		Befehl ausgeführt, und eine Zeichenfolge in einfachen Anführungszeichen ist ein literaler 
		Zeichenfolgenbefehl.
[/Edit]

Gruß Phil
Biber
Biber 09.09.2011 um 00:27:09 Uhr
Goto Top
Moin pieh-ejdsch,

wäre es, wenn die Anführungszeichen als Delimiter zwischen mehreren Token dienen sollen,
nicht angebrachter, die FOR-Anweisung so zu formulieren?
>for /f usebackq^ tokens^=1-6^ delims^=^"  %i in ("e:\schnipsel\textmitAnfü.txt") do @echo i[%i] j[%j] k[%k] l[%l] m[%m] n[%n]
i[diese Zeile enth§lt kein AnfuerungsZeichen] j k l m n
i[dieser Text enthaelt hier ->] j[ ein Anfuerungszeichen] k l m n
i[diese] j[Zeile] k[ist] l[mit] m[AnfuerungsZeichen] n[zwischen]

Die Textdatei "textmitAnfü.txt" sieht so aus:
diese Zeile enthõlt kein AnfuerungsZeichen
dieser Text enthaelt hier ->" ein Anfuerungszeichen
diese"Zeile"ist"mit"AnfuerungsZeichen"zwischen"Den"Worten

Oder - anders ausgedrückt - mit der Caret/dem Zirkumflex ^ ein Anführungszeichen innerhalb der FOR-Anweisung zu maskieren mag ja eine notwendige Bedingung sein.
Aber für die Nutzbarkeit als delimiter ist es nicht hinreichend.

Grüße
Biber
[Edit & OT]
in dem Sinne ist es kein Satzzeichen, sondern Korrekterweise ist es nur ein "Zollzeichen".
...in diesem Forum bestimmt auch bald als "hochgestellte römische Zwei" bezeichnet, weil es sonst zu einfach wird.
Ich denke, Kaputtnick hatte sich nur an den doppelten Anführungszeichen gestört.
Weil.... du bekommst auch keine anderen, wenn du im Laden nach einfachen handelsüblichen Anführungszeichen fragst.
[/Edit & OT]
Friemler
Friemler 10.09.2011 um 13:34:52 Uhr
Goto Top
Moin pieh-ejdsch,

schön, dass Du das herausgefunden und veröffentlicht hast. Dieser Tipp wird in meinem FOR-Tutorial verlinkt face-smile .

Zur Bezeichnung des "-Zeichens: Ich denke, man sollte sich da einfach an den allgemeinen Sprachgebrauch halten. Die Ausdrücke "doppeltes Anführungszeichen" (für das "-Zeichen), "einfaches Anführungszeichen" (für das '-Zeichen, was eigentlich Apostroph heißt) und "umgekehrtes Anführungszeichen" (für das `-Zeichen, was eigentlich Gravis oder frz. accent grave heißt) stammt ja schließlich von den Übersetzern der Hilfetexte der Redmonder Praktikanten, die wahrscheinlich ebenfalls Praktikanten waren face-wink ... Diese sprachlichen Ver(w)irrungen noch fortzusetzen und den Begriff "Zollzeichen" ins Spiel zu bringen, halte ich für keine gute Idee. Und laut dem Wikipedia-Artikel ist das "-Zeichen ein Satzzeichen.

Gruß
Friemler
Skyemugen
Skyemugen 12.09.2011 um 08:49:25 Uhr
Goto Top
Aloha Friemler,
[OT]
und nur weil's bei FWikipedia steht ...

Ich persönlich bleibe bei Zollzeichen, weil ich „Anführungszeichen” weder aus dem ASCII heraus noch sonstwie schreibmaschinentechnisch im heutigen Zeitalter akzeptiere face-wink [auch wenn viele Forensoftware sowohl für “ (ALT+0147) als auch für ” (ALT+0148) oftmals nur " darstellen oder die Darstellung sogar vertauschen *gg*]
[/OT]

@phil,

hättest du den Beitrag nicht vor zwei Wochen bringen können ... ich hab mir den ... ausgebissen, Zollzeichen als Delimiter zu nutzen, auf die Idee, die Optionen zu maskieren wäre ich dort nicht gekommen.

greetz André

edit: Weshalb funktioniert das eigentlich nicht mit in ('echo Eins"Zwei"Drei"etc') ?

P.S.:@Phil, wenn dann bitte Skye face-wink
pieh-ejdsch
pieh-ejdsch 12.09.2011 um 18:48:37 Uhr
Goto Top
moin Skye,

vor zwei Wochen also - hättest ja einen Beitrag öffnen Können face-wink

das mit dem Nichtfunktionieren - gegenfrage wieviel AnführungsZeichen sind denn im Satz der For?
um ein kleines Licht dort hineinzubringen habe ich mal was Vorbereitet
in dem Teil der Variable wo in der Forschleife auch Fehler kommen hängt genau mit dem Bereich der Variable zusammen wo eine Maskierung greift und wo nicht.
eine Andere Variante für Tee ist auch eingebaut Batch - mit und ohne tee - Konsoleausgaben zugleich in eine Datei leiten und auf dem Bildschirm ausgeben
@echo off&setlocal
if not "%~1" == "" goto :Weiter  
set "E=echo on"&set "A=@echo off"  

set "Log=1>>"%temp%\CMD.log" 2>&1 "  

prompt $g
if not defined Log goto :NoLog
type nul>"%temp%\CMD.log.on"  
type nul>"%temp%\CMD.log"  
start "Test Ausgabe" "%~0" Out  
ping localhost -n 2 >nul
:NoLog
%log%(
for %%i in (Test0 Test1 Test2 Test3 Test4) do cmd /c ""%~0" %%i"  
)
:: 
del "%temp%\CMD.log.on"  
if not defined Log pause
goto :eof

:weiter
goto :%~1


:Out
for %%i in ("%temp%\CMD.log") do set /a Gr = %%~zi  
for /f %%i in ('find /v /c "" ^< "%temp%\CMD.log" 2^>nul ') do set /a lastline = %%i  
:Out2
if not exist "%temp%\CMD.log.on" (echo\&echo\Programm beendet&pause&exit)  
for %%i in ("%temp%\CMD.log") do if "%%~zi" neq "%Gr%" (set /a Gr = %%~zi ) else goto :Out2  
for /f %%i in ('" find /v /c "" < "%temp%\CMD.log" 2>nul "') do if %%i neq %lastline% set /a lastline = %%i&more +%lastline% "%temp%\CMD.log"|find /v ""  
goto :Out2


:test0
@echo off&setlocal
echo Dieser Test soll Zeigen in welchen Bereichen zwischen AnfuehrungsZeichen
echo eine Maskierung mit dem Zirkumflex Funktioniert
echo Wenn nur das ZirkumFlex Maskiert wir ist der Effekt schon beim setzen
echo der Variablen erkennbar in welchem Bereich eine Maskierung Funktioniert
%e%
set "Test=                             " Maskierbar ^^ "  
set "Test=KEIN Maskierbarer Bereich ^^ "              "  
%a%
echo\
goto :eof


:test1
%e%
set "Test=a   b	c"1 1   1!2	2		2^^"  def	" ghi"  
%a%
echo Test voll:
echo %Test%
%e%
for /f eol^=^"^ delims^=^"^!^ tokens^=1^,2-5 %%i in ("%Test%") do @echo\Test aus der For: 1%%i.2%%j.3%%k.4%%l.5%%m.  
%a%
echo Hier ist schon erkennbar das im Maskierbaren Bereich die Leerzeichen und Tab
echo zu einem Leerzeichen zusammengezogen werden.
%e%
set "Test="   .a		.b .c""  
for /f "delims=. tokens=1-3" %%i in ("%Test%") do @echo\Test aus der For: 1%%i.2%%j.3%%k.  
%a%
echo Das war Test Nr. 1 - diese Maskierung funktioniert.
echo\
goto :eof


:test2
echo Zum zweiten Test ...

%e%
set "Test=a   b	c"1 1   1!2	2		2^^"  def	^^" ghi"  
%a%
echo im Set wird die Zweite Maskierung trozdem trozdem nicht ausgefuehrt
echo Test        voll:
echo %Test%
echo\
%e%
for /f eol^=^"^ delims^=^"^!^ tokens^=1^,2-5 %%i in ("%Test%") do @echo\Test aus der For: 1%%i.2%%j.3%%k.4%%l.5%%m.  
%a%
echo Das war Test Nr.2 - die Zweite Maskierunge funktioniert Nicht.
echo obwohl die erste Maskierung greift bleibt der Zweite Abschnitt Unmaskierbar
echo sonst wuerde bei ungerader Anzahl Anführungszeichen die For nicht klappen
echo\
goto :eof


:test3
echo Zum dritten Test ...
%e%
set "Test=a   b	c"1 1   1!2	2		2"  def	^" ghi"  
%a%
echo die Zweite Maskierung mit nur "einem" Zirkumflex  
echo Test        voll:
echo %Test%
echo\
%e%
for /f eol^=^"^ delims^=^"^!^ tokens^=1^,2-5 %%i in ("%Test%") do @echo\Test aus der For: 1%%i.2%%j.3%%k.4%%l.5%%m.  
goto :eof


:test4
echo Das war Test Nr.3 - die Zweite Maskierung funktioniert Nicht.
echo der Zweite Abschnitt bleibt Unmaskierbar
echo\
echo Zum vierten Test ...
%e%
set "Test=a   b	c"1 1   1!2	2		2"  def	^^" ghi"  
%a%
echo Test        voll: %Test%
echo Die ForSchleife wird nicht ausgefuehrt
for /f eol^=^"^ delims^=^"^!^ tokens^=1^,2-5 %%i in ("%Test%") do @echo\Test aus der For: 1%%i.2%%j.3%%k.4%%l.5%%m.  

Da kann man sich anstrengen wie man will der Unmaskierbare Bereich bleibt unmaskierbar! Siehe: ->fast ganz oben
Lösung Txt verwenden oder Verzögerte Auflösung.

Gruß Phil
jeb-the-batcher
jeb-the-batcher 10.10.2011 um 09:11:11 Uhr
Goto Top
@pieh-ejdsch

Ich bin begeistert, nachdem eigentlich niemand mehr geglaubt hat, dass es möglich ist quotes als delim zu verwenden, ist es doch noch gelungen.
Und dann auf eine so relativ einfache Weise, nur dass es vorher nie jemand ausprobiert hat.
Ich hab auch so ziemlich alles probiert, aber auf die Idee die umschliessenden quotes wegzulassen bin ich einfach nicht gekomment.

Jan Erik