Das Entfernen von doppelten Anführungszeichen aus Variablen in der Batchdatei führt zu Problemen mit der CMD-Umgebung

116

Kann jemand helfen, Anführungszeichen effektiv und sicher aus Stapelvariablen zu entfernen?

Ich habe eine Batch-Datei geschrieben, die erfolgreich eine Liste der Parameter% 1,% 2,% 3 usw. importiert und in benannte Variablen einfügt. Einige dieser Parameter enthalten mehrere Wörter und sind daher in doppelte Anführungszeichen eingeschlossen.

> "Susie Jo" (%1)  
> "Smith Barnes" (%2)  
> "123 E. Main St." (%3)  

Diese% -Variablen werden als nächstes in benannte Variablen eingefügt:

> set FirstName=%1  
> set LastName=%2  
> set ShipAddr=%3  

Die Überprüfung der Variablen erfolgt durch Echo.

echo.% Vorname%
echo.% Nachname%
echo.% ShipAddr%

Ergebnisanzeige als

"Susie Jo"  
"Smith Barnes"  
"123 E. Main St."  

Ich muss die enthaltenen Anführungszeichen für ausgewählte Variablen entfernen. Beispielsweise werden Vorname und Nachname an anderer Stelle verwendet und dürfen keine Anführungszeichen enthalten.

In einer Test-Batch-Datei konnte ich Anführungszeichen mit dem Zeichen ~ tilde in Variablen erfolgreich entfernen.

> set FirstName=%~1
> set LastName=%~2 

Ich dachte, ich hätte die Lösung, aber ich hatte bald ungewöhnliches Verhalten bei der Ausführung von Batch-Dateien. Plötzlich erkennt CMD keine Long-Path-Statements mehr. Normale Ausführung der Batchdatei vom vollständigen Pfad

> C:\Documents and Settings\Administrator\My Documents\Txt\batchtest\dataout.bat

kehrt zurück

> 'C:\Documents' is not recognized as an internal or external command....

Es scheint also, dass das Hinzufügen des ~ Tilde-Zeichens zu den eingehenden% 1% 2 ...% n-Variablen einige Änderungen verursacht hat. Möglicherweise wurden einige Umgebungsvariablen geändert?

Ich habe auch versucht, Anführungszeichen aus einer Variablen mit verschiedenen Versuchen mit dem Befehl FOR zu löschen. Das scheint unangenehm und ich konnte nicht lernen, wie dies durch Erstellen einer Liste von Variablen zur Ausführung der Aufgabe erreicht werden kann:

etwas wie das:

for %%g in (%FirstName% %LastName%) do (
set %%g=%%~g
set %%h=%%~h
set FirstName=%%~g
set LastName=%%h
echo.%FirstName% %LastName%
)

Ich glaube, ich habe zwei Probleme.

1) Meine 'kurze und süße' Idee, ~ Tilde in die eingehenden% 1% 2-Variablen (% ~ 1 usw.) einzufügen, scheint einige Einstellungen beeinflusst und die Navigation von CMD durch lange Pfadnamen geändert zu haben.

2) Ich bin immer noch auf der Suche nach einer sauberen und einfachen Möglichkeit, Anführungszeichen aus ausgewählten benannten Variablen zu entfernen.

Jede Hilfe für erfahrene Personen wäre sehr dankbar. Ich bin am Ende meiner Fähigkeiten hier ... brauche bitte eine Anleitung!

bearbeiten 26.12.2009 13:36 PST gesamte Batch-Datei:

Blockquote
:: dataout.bat
:: revision 25.12.2009 Fügen Sie ~ tilde zu eingehenden% -Variablen hinzu, um eingebettete "Anführungszeichen" zu entfernen.
:: schreibt Adressliste mit Befehlszeilenparametern
:: schreibt Datenausgabeliste für QBooks IIF-Import
:: schreibt Händlerbestelldaten für RUI
:: Beispielbefehlszeilenzeichenfolge zum Testen
:: listmail [Vorname] [Nachname] ["Adresszeichenfolge"] ["Stadtzeichenfolge"] [Bundesland] [Postleitzahl] [Bestellnummer] [Kaufdatum] [Registrierungsname] ["Vorname Nachname"] [Transaktions-ID] [Zahlungsmethode] [Gesamt] [Produkt-ID] [Menge] [Preis_Jeder] [PackPrep] [Versand] [ProvisionPmt] [Rechnungsnummer]
:: Beispiel: Datenausgabe Bellewinkle Moose "123 Green Forest Way" "Vancouver" WA 98664 1004968 25.05.2009 "Bellewinkle Moose" "Olive Oyl" 101738 "On Account" 20.67 FK-1P 1 8.95 3.00 1.39 239
@echo off
cls
c:
cd \
cd Dokumente und Einstellungen \ Administrator \ meine Dokumente \ txt \ batchtest
Echo-Verarbeitung% 1% 2
: VARISET
::Konvertieren Sie% n Befehlszeilenparameter in Zeichenfolgenvariablen
set ($ FirstName) =% ~ 1
set ($ LastName) =% ~ 2
set ($ BillingAddress1) =% ~ 3
set ($ BillingCity) =% ~ 4
set ($ BillingState) =% ~ 5
set ($ BillingPostal) =% ~ 6
set ($ OrderNumber) =% ~ 7
set ($ Purch_Date) =% ~ 8
set ($ RegistrationName) =% ~ 9
Schichtsatz
($ TransactionID) =% ~ 9
Schichtsatz
($ PaymentMethod) =% ~ 9
Schichtsatz
($ Total) =% ~ 9
Schichtsatz ($ ProductIdentifier) ​​=% ~ 9
Schichtsatz
($ Quantity) =% ~ 9
Schichtsatz
($ Price_Each) =% ~ 9
Schichtsatz
($ Pack_Prep) =% ~ 9
Schichtsatz
($ Versand) =% ~ 9
Schichtsatz
($ ServiceFee) =% ~ 9
Schichtsatz
($ Rabatt) =% ~ 9
Schichtsatz
($ Rechnung) =% ~ 9
Schichtsatz
($ UnitPrice) =% ~ 9
Satz _ShipCombName =% ($ Vorname) %% ($ Nachname)%
Echo Schiffskombinationsname ist% _ShipCombName%
Pause
:: Zeichenfolgenvariablen in das Protokolldateiecho schreiben
FN% ($ Vorname)% LN% ($ Nachname)% BA% ($ BillingAddress1) %% ($ BillingCity) %% ($ BillingState) %% ($ BillingPostal) %% ($ Bestellnummer) %% ($ Purch_Date) %% ($ RegistrationName) %% ($ TransactionID) %% ($ PaymentMethod) %% ($ Total) %% ($ ProductIdentifier) ​​%% ($ Quantity) %% ($ Price_Each) %% ($ Pack_Prep) %% ($ Versand) %% ($ ServiceFee) %% ($ Rabatt) %% ($ Rechnung) %% ($ UnitPrice) %% _ShipCombName% >> d_out_log.txt
:: Konto zuweisen nach Dienstanbieter
IF / i% ($ PaymentMethod)% == Amazon Receivables SET _QBAcct = Amazon.com
:: 25.12.2009 zweite Amazon pm't-Methode für Vielseitigkeit hinzugefügt
IF / i% ($ PaymentMethod)% == Amazon SET _QBAcct = Amazon.com
IF / i% ($ PaymentMethod)% == MAST SET _QBAcct = Auth / Net
IF / i% ($ PaymentMethod)% == MasterCard SET _QBAcct = Auth / Net
IF / i% ($ PaymentMethod)% == Visa SET _QBAcct = Auth / Net
IF / i% ($ PaymentMethod)% == PayPal SET _QBAcct = PayPalPmts
IF / i% ($ PaymentMethod)% == Auf Konto SET _QBAcct =% ($ RegistrationName)%
IF / i% ($ PaymentMethod)% == Mail SET _QBAcct =% ($ RegistrationName)%
IF / i% ( $ PaymentMethod)% == AMER SET _QBAcct = Auth / Net
IF / i% ($ PaymentMethod)% == DISC SET _QBAcct = Auth / Net
:: Rep-Bezeichner basierend auf QBAccount
IF / i% ($ PaymentMethod)% == Amazon Receivables SET _Rep = Amazon
:: 25.12.2009 zweite Amazon pm't-Methode für Vielseitigkeit hinzugefügt
IF / i% ($ PaymentMethod)% == Amazon SET _Rep = Amazon
IF / i% ($ PaymentMethod)% == MAST SET _Rep = BlueZap
IF / i% ($ PaymentMethod)% == MasterCard SET _Rep = BlueZap
IF / i% ($ PaymentMethod)% == Visa SET _Rep = BlueZap
IF / i% ($ PaymentMethod)% == PayPal SET _Rep = BlueZap
IF / i% ($ PaymentMethod)% == Auf Konto SET _Rep = RB
IF / i% ($ PaymentMethod)% == Mail SET _Rep = RB
IF / i% ($ PaymentMethod)% == AMER SET _Rep = BlueZap
IF / i % ($ PaymentMethod)% == DISC SET _Rep = BlueZap
:: auf doppelte Adressdaten prüfen
findstr / i / s "% _ShipCombName%" addrlist.txt
echo errorlevel:% errorlevel%
if errorlevel 1 goto: ADDRWRITE
if errorlevel 0 goto: ADDRFOUND
: ADDRWRITE
echo% _ShipCombName% >> addrlist.txt
echo% ($ BillingAddress1)% >> addrlist.txt
echo% ($ BillingCity) %% ($ BillingState) %% ($ BillingPostal)% >> addrlist.txt
echo. >> addrlist.txt
echo Adressdatei Geschrieben
: ADDRFOUND
echo ausgewählter Vertreter ist% _Rep%
echo ausgewähltes Konto ist:% _QBAcct%
pause
:: RUI OUT
:: Händlerbestell- ID & RUI- Bestell- ID in RUI schreiben
:: auf doppelte RUI-Daten prüfen in writeRUI.txt
cd ..
cd RegKOut
find / i "% ($ OrderNumber)%" writeRUI.txt
echo errorlevel:% errorlevel%
wenn errorlevel 1 gehe zu: RUIWRITE
wenn errorlevel 0 gehe zu
: IIFWRITE: RUIWRITE
echo% ($ Invoice)% % ($ OrderNumber)% >> writeRUI.txt
:: end write RUI
:: IIF OUT
: IIFWRITE
:: In writeIIF.txt auf doppelte Rechnungsdaten prüfen
find / i "% ($ OrderNumber)%" writeIIF.txt
echo errorlevel:% errorlevel%
if errorlevel 1 goto: HEADWRITE
if errorlevel 0 goto: LINEWRITE
: HEADWRITE
:: write Header-, Versand- / Bearbeitungs-, Rabatt-, Rep- und Provisionsdaten in die QB IIF-
Importdatei echo% ($ OrderNumber) %% ($ Purch_Date)% Invoice% ($ TransactionID) %% _QBAcct% Debitorenbuchhaltung% ($ Total) %% _Rep % >> writeIIF.txt
echo H / P% ($ Pack_Prep)% 1? >> writeIIF.txt
echo SHP% ($ Shipping)% 1? >> writeIIF.txt
echo DISC% ($ Discount)% 1? >> writeIIF.txt
Echo Comm% ($ ServiceFee)% 1? >> writeIIF.txt
: LINEWRITE
IF / i% ($ ProductIdentifier)% equ PH-1 gehe zu WRITE_DEFA ELSE gehe zu WRITE_DISC
echo% ($ ProductIdentifier)%
: WRITE_DISC
:: schreibt reduzierte Preise, die aus der benutzerdefinierten Variablen analysiert werden:
echo% ($ ProductIdentifier) %% ($ Price_Each) %% ($ Quantity)%? >> writeIIF.txt gehe zu
: EOF
: WRITE_DEFA
: schreibt Standardpreise, die aus Produktdaten analysiert wurden
echo% ($ ProductIdentifier) ​​%% ($ UnitPrice) %% ($ Quantity)%? >> writeIIF.txt gehe zu
: EOF
:: 3 Sekunden Verzögerung
:: TYP NUL | CHOICE.COM / N / CY / TY, 3> NUL
: EOF

BobB
quelle
Könnten Sie dazu PowerShell verwenden? Ich vermute, Sie erhalten etwas mehr Kontrolle, wenn Sie PowerShell verwenden.
Robert Harvey
1
Ich habe Ihre Batch-Datei überprüft - sie scheint gut zu funktionieren (nachdem ich die Zeile "Shift Set ($ ProductIdentifier) ​​=% ~ 9" korrigiert habe - was meiner Meinung nach ein Artefakt beim Kopieren und Einfügen ist).
Atzz
Vielen Dank, dass Sie Robert Harvey; Ich habe PowerShell beobachtet. Ich bin nicht sehr erfahren mit Programmieren. Ich bin mir nicht sicher, wie die Lernkurve aussehen würde. Ich habe einige Erfahrungen mit Batch-Dateien, Hauptgrund, warum ich mich dafür entschieden habe. Ich beabsichtige, den Stapel zu kompilieren, damit er schneller ausgeführt wird. Danke für die Antwort.
BobB
Danke atzz: Ich habe diese Batch-Datei seitdem noch einmal getestet und bin ziemlich sicher, dass die ~ Tilde- und Banishing-Anführungszeichen nichts mit dem CMD-Problem mit langen Pfadnamen zu tun haben. Ich habe das umgangen, indem ich einfach ein Kurznamen-Unterverzeichnis in der Nähe der Wurzel eingerichtet habe, um lange Pfadnamen zu eliminieren.
BobB
Es ist nicht erforderlich, die vollständige Batchdatei anzuzeigen. Bitte kürzen Sie Ihre Frage.
jor

Antworten:

191

Am Ende steht ein zusätzliches doppeltes Anführungszeichen, das am Ende der Zeichenfolge wieder hinzugefügt wird (nachdem beide Anführungszeichen aus der Zeichenfolge entfernt wurden).

Eingang:

set widget="a very useful item"
set widget
set widget=%widget:"=%
set widget

Ausgabe:

widget="a very useful item"
widget=a very useful item

Hinweis: Um doppelte Anführungszeichen durch einfache Anführungszeichen zu ersetzen, gehen Sie wie folgt vor:

set widget=%widget:"='%

Hinweis: Um das Wort "Welt" (ohne Berücksichtigung der Groß- und Kleinschreibung) durch BobB zu ersetzen, gehen Sie wie folgt vor:

set widget="Hello World!"
set widget=%widget:world=BobB%
set widget

Ausgabe:

widget="Hello BobB!"

Was Ihre erste Frage betrifft (speichern Sie den folgenden Code in einer Batch-Datei .cmd oder .bat und führen Sie ihn aus):

@ECHO OFF
ECHO %0
SET BathFileAndPath=%~0
ECHO %BathFileAndPath%
ECHO "%BathFileAndPath%"
ECHO %~0
ECHO %0
PAUSE

Ausgabe:

"C:\Users\Test\Documents\Batch Files\Remove Quotes.cmd"
C:\Users\Test\Documents\Batch Files\Remove Quotes.cmd
"C:\Users\Test\Documents\Batch Files\Remove Quotes.cmd"
C:\Users\Test\Documents\Batch Files\Remove Quotes.cmd
"C:\Users\Test\Documents\Batch Files\Remove Quotes.cmd"
Press any key to continue . . .

%0ist der Skriptname und der Pfad.
%1ist das erste Befehlszeilenargument und so weiter.

Mr. Rick
quelle
Danke, das war es, wonach ich SET BathFileAndPath=%~0gesucht habe (eigentlich beginnt mein Parameter-Array mit 1, also habe ich es verwendetSET BathFileAndPath=%~1
Valamas
Können Sie erklären, warum %widget:"=%die Anführungszeichen entfernt werden?
CodyBugstein
4
@Imray - Dies :old=newist eine Musterübereinstimmung und Ersetzung in der Variablenerweiterung. Mit so "wie oldund nichts wie das newwerden die Anführungszeichen entfernt, auch wenn sie in der Mitte sind, auch wenn sie unausgeglichen sind.
Jesse Chisholm
set widget =% widget: "=% hat ein seltsames Verhalten, wenn das Widget leer ist, es gibt" = "zurück
Rahul Misra
43

Ihre Schlussfolgerung (1) klingt falsch. Es muss noch einen anderen Faktor geben.

Das Problem von Anführungszeichen in Batchdatei-Parametern wird normalerweise gelöst, indem die Anführungszeichen mit entfernt %~und gegebenenfalls manuell zurückgesetzt werden.

Z.B:

set cmd=%~1
set params=%~2 %~3

"%cmd%" %params%

Beachten Sie die Anführungszeichen %cmd%. Ohne sie funktioniert ein Pfad mit Leerzeichen nicht.

Wenn Sie Ihren gesamten Stapelcode veröffentlichen könnten, könnte möglicherweise eine spezifischere Antwort gegeben werden.

atzz
quelle
1
Ich stimme zu; scheint mir, dass die Menge var =% ~ 1 gut funktionieren sollte. Ich werde die gesamte Batch-Datei wie gewünscht veröffentlichen.
BobB
MS-Referenz: Verwenden von Stapelparametern . Wer wusste, dass es so viele Modifikatoren gibt? Als Referenz gibt das offizielle MS-Dokument die Beschreibung von %~1asExpands %1 and removes any surrounding quotation marks ("").
cod3monk3y am
@ cod3monk3y Es ist auch möglich, cmdsich nach diesen Modifikatoren zu fragen : call /?Hilfe zu Parametermodifikatoren, set /?zu variablen Modifikatoren (wahrscheinlich nicht sehr intuitiv). Sehr praktisch.
Atzz
11

Normalerweise entferne ich einfach alle Anführungszeichen aus meinen Variablen mit:

set var=%var:"=%

Und dann wieder anwenden, wo immer ich sie brauche, zB:

echo "%var%"
t1ck
quelle
Anfangs hatte ich auch Probleme damit, es stellte sich heraus, dass ich das :als .- nachdem ich das herausgefunden hatte, ohne Probleme funktionierte. Toller Tipp!
DaveU
9

Ich habe viel Zeit damit verbracht, dies auf einfache Weise zu tun. Nachdem ich mir die FOR-Schleife genau angesehen hatte, wurde mir klar, dass ich dies mit nur einer Codezeile tun kann:

FOR /F "delims=" %%I IN (%Quoted%) DO SET Unquoted=%%I

Beispiel:

@ECHO OFF
SET Quoted="Test string"

FOR /F "delims=" %%I IN (%Quoted%) DO SET Unquoted=%%I

ECHO %Quoted%
ECHO %Unquoted%

Ausgabe:

"Test string"
Test string
Vitaliy Ulantikov
quelle
Diese Methode ist nicht relevant, solange "SET Quoted = Test string". Die nächste Frage ist, wie man sich unterscheidet, ob "(doppeltes Anführungszeichen) existiert oder nicht. Wem könnte es etwas
ausmachen
3

Dies klingt nach einem einfachen Fehler, bei dem Sie% ~ irgendwo verwenden, wo Sie nicht sein sollten. Die Verwendung von% ~ ändert die Funktionsweise von Batchdateien nicht grundlegend, sondern entfernt nur Anführungszeichen aus der Zeichenfolge in dieser einzelnen Situation.

John Knoeller
quelle
3

Ich habe aus diesem Link gelernt , dass dies bei sich selbst funktioniert, wenn Sie XP oder höher verwenden:

SET params = %~1

Ich konnte hier keine der anderen Lösungen für Windows 7 finden.

Um sie zu wiederholen, habe ich Folgendes getan:

FOR %%A IN (%params%) DO (    
   ECHO %%A    
)

Hinweis: Sie erhalten nur doppelte Anführungszeichen, wenn Sie Argumente übergeben, die normalerweise durch ein Leerzeichen getrennt sind.


quelle
0
  1. set widget = "ein sehr nützliches Element"
  2. Widget einstellen
  3. widget = "ein sehr nützlicher Gegenstand"
  4. set widget =% widget: "=%"
  5. Widget einstellen
  6. set widget = ein sehr nützliches Element "

Das nachfolgende Anführungszeichen "in Zeile 4 fügt "der Zeichenfolge ein Anführungszeichen hinzu . Es sollte entfernt werden. Die Syntax für Zeile 4 endet mit%

David
quelle
@ user195488 - Lesen Sie Zeile 3 so , wie es angezeigt wird:widget="a very useful item" und lesen Sie Zeile 6 so , wie es angezeigt wird:widget=a very useful item" und verstehen Sie, dass Zeile 7 set widget=%widget:"=%und Zeile 8 so ist , dass die angezeigte Zeile widget=a very useful itemkein nachfolgendes Anführungszeichen mehr enthält .
Jesse Chisholm
0

Ich dachte, ich hätte die Lösung, aber ich hatte bald ungewöhnliches Verhalten bei der Ausführung von Batch-Dateien. Plötzlich erkennt CMD keine Long-Path-Statements mehr. Normale Ausführung der Batchdatei vom vollständigen Pfad

C: \ Dokumente und Einstellungen \ Administrator \ Eigene Dateien \ Txt \ batchtest \ dataout.bat

kehrt zurück

'C: \ Documents' wird nicht als interner oder externer Befehl erkannt ....

Da ist dein ganzes Problem. CMD versteht keine Leerzeichen innerhalb von Dateinamen über die Befehlszeile und glaubt daher, dass Sie versuchen zu übergeben

und Einstellungen \ Administrator \ Eigene Dateien \ Txt \ batchtest \ dataout.bat

als Parameter zum

"C: \ Dokumente"

Programm.

Sie müssen es in Anführungszeichen setzen, um eine Batchdatei mit Leerzeichen im Pfad auszuführen:

> "C:\Documents and Settings\Administrator\My Documents\Txt\batchtest\dataout.bat"

hätte funktioniert.

CarryWise
quelle
0
@echo off

Setlocal enabledelayedexpansion

Set 1=%1

Set 1=!1:"=!

Echo !1!

Echo "!1!"

Set 1=

Demonstriert mit oder ohne Anführungszeichen, unabhängig davon, ob der ursprüngliche Parameter Anführungszeichen enthält oder nicht.

Wenn Sie die Existenz eines Parameters testen möchten, der möglicherweise in Anführungszeichen steht oder nicht, setzen Sie diese Zeile vor die obigen Echos:

Wenn '% 1' == '' gehe zu deinem Sub

Wenn Sie jedoch prüfen, ob eine Datei vorhanden ist, die möglicherweise Anführungszeichen enthält, können Sie Folgendes tun:

Wenn EXISTIERT "! 1!" gehe zu anderen

Beachten Sie, dass die Verwendung von einfachen und doppelten Anführungszeichen unterschiedlich ist.

Aaron Lowe
quelle
0

Alle Antworten sind vollständig. Aber wollte eine Sache hinzufügen,

setze Vorname =% ~ 1

setze Nachname =% ~ 2

Diese Zeile hätte funktionieren sollen, Sie brauchten eine kleine Änderung.

setze "Vorname =% ~ 1"

setze "Nachname =% ~ 2"

Fügen Sie die vollständige Zuordnung in Anführungszeichen ein. Anführungszeichen werden ohne Probleme entfernt. Dies ist eine bevorzugte Zuweisungsmethode, mit der unerwünschte Probleme mit Anführungszeichen in Argumenten behoben werden.

Codename Jack
quelle
0

Die einfache Tilde-Syntax dient nur zum Entfernen von Anführungszeichen um die Befehlszeilenparameter, die an die Batch-Dateien übergeben werden

SET xyz=%~1

Der obige Batch-Dateicode setzt xyz auf den Wert, der als erster Parameter übergeben wird, wobei die führenden und nachfolgenden Anführungszeichen (falls vorhanden) entfernt werden.

Diese einfache Tilde-Syntax funktioniert jedoch nicht für andere Variablen, die nicht als Parameter übergeben wurden

Für alle anderen Variablen müssen Sie die erweiterte Substitutionssyntax verwenden, bei der Sie führende und nacheilende Zeichen angeben müssen, die entfernt werden sollen. Tatsächlich weisen wir Sie an, das erste und das letzte Zeichen zu entfernen, ohne zu sehen, was es tatsächlich ist.

@SET SomeFileName="Some Quoted file name"
@echo %SomeFileName% %SomeFileName:~1,-1%

Wenn wir überprüfen möchten, was das erste und letzte Zeichen tatsächlich in Anführungszeichen steht, bevor wir es entfernen, benötigen wir wie folgt zusätzlichen Code

@SET VAR="Some Very Long Quoted String"
If aa%VAR:~0,1%%VAR:~-1%aa == aa""aa SET UNQUOTEDVAR=%VAR:~1,-1%
user13490680
quelle