La rimozione di virgolette doppie dalle variabili nel file batch crea problemi con l'ambiente CMD


117

Qualcuno può aiutare con un modo efficace e sicuro per rimuovere le virgolette dalle variabili batch?

Ho scritto un file batch che importa con successo un elenco di parametri% 1,% 2,% 3 ecc. E li inserisce in variabili denominate. Alcuni di questi parametri contengono più parole e pertanto sono racchiusi tra virgolette doppie.

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

Queste variabili% vengono poi inserite nelle variabili denominate:

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

la verifica delle variabili viene eseguita tramite eco.

echo.% FirstName%
echo.% LastName%
echo.% ShipAddr%

i risultati vengono visualizzati come

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

Devo eliminare le virgolette incluse sulle variabili selezionate. Ad esempio, FirstName e LastName vengono utilizzati altrove e non devono includere virgolette.

In un file batch di prova sono riuscito a eliminare le virgolette utilizzando il carattere ~ tilde nelle variabili.

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

Pensavo di avere la soluzione, ma presto ho riscontrato un comportamento insolito con l'esecuzione di file batch. Improvvisamente CMD non riconosce le dichiarazioni di percorso lungo. Esecuzione normale del file batch dal percorso completo

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

ritorna

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

Quindi sembrerebbe che l'aggiunta del carattere ~ tilde alle variabili% 1% 2 ...% n in arrivo abbia causato qualche cambiamento. Forse alcune variabili d'ambiente sono state alterate?

Ho anche provato a cancellare le virgolette dall'interno della variabile con vari tentativi utilizzando il comando FOR. Sembra imbarazzante e non sono stato in grado di imparare come farlo creando un elenco di variabili per eseguire l'attività:

qualcosa come questo:

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

Penso di avere due problemi.

1) La mia idea "breve e dolce" di inserire ~ tilde nelle variabili% 1% 2 in arrivo (% ~ 1, ecc.) Sembra aver influenzato alcune impostazioni e modificato il modo in cui CMD naviga nei nomi di percorso lunghi.

2) Sono ancora alla ricerca di un modo semplice e pulito per eliminare le virgolette dalle variabili nominate selezionate.

Qualsiasi aiuto per i più esperti sarebbe molto apprezzato. Sono alla fine delle mie capacità qui ... ho bisogno di una guida per favore!

modifica 26/12/2009 13:36 PST intero file batch:

Blockquote
:: dataout.bat
:: revisione 12/25/2009 aggiunge ~ tilde alle variabili% in arrivo per eliminare le virgolette "incorporate.
:: scrive l'elenco di indirizzi utilizzando i parametri della riga di comando
:: scrive l'elenco di output dei dati per QBooks IIF import
:: scrive Dati dell'ordine commerciante per RUI
:: stringa della riga di comando di esempio per testing
:: listmail [firstname] [lastname] ["address string"] ["city string"] [state] [zip] [Order #] [PurchDate] [Regname] ["FirstName LastName"] [TransactionID] [PaymentMethod] [Total] [ProductID] [Qty] [Price_Each] [PackPrep] [Shipping] [CommissionPmt] [Invoice #]
:: esempio: dataout 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 documenti e impostazioni \ amministratore \ miei documenti \ txt \ batchtest
echo elaborazione% 1% 2
: VARISET
::Converti i parametri della riga di comando% n nel
set di variabili stringa ($ 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

set di turni ($ TransactionID) =% ~ 9 set di
turni
($ PaymentMethod) =% ~ 9
turni
($ Total) =% ~ 9
turni ($ ProductIdentifier) ​​=% ~ 9
turni
($ Quantity) =% ~ 9 set
turni
($ Price_Each) =% ~ 9
turni
($ Pack_Prep) =% ~ 9
turni
($ Spedizione) =% ~ 9
turni
($ ServiceFee) =% ~ 9
turni
($ Sconto) =% ~ 9 set di
turni
($ Invoice) =% ~ 9 set di
turni
($ PrezzoUnitario) =% ~ 9
set _ShipCombName =% ($ FirstName)%% ($ LastName)%
echo il nome della combinazione nave è% _ShipCombName%
pause
:: scrive variabili di stringa nel file di log
echo FN% ($ FirstName)% LN% ($ LastName)% BA% ($ BillingAddress1)%% ($ BillingCity)%% ($ BillingState)%% ($ BillingPostal)%% ($ OrderNumber)%% ($ Purch_Date)%% ($ RegistrationName)%% ($ TransactionID)%% ($ PaymentMethod)%% ($ Total)%% ($ ProductIdentifier)%% ($ Quantity)%% ($ Price_Each) %% ($ Pack_Prep)%% ($ Shipping)%% ($ ServiceFee)%% ($ Discount)%% ($ Invoice)%% ($ UnitPrice)%% _ShipCombName% >> d_out_log.txt
:: Assign Account by Fornitore di servizi
IF / i% ($ PaymentMethod)% == Amazon Receivables SET _QBAcct = Amazon.com
:: 12-25-2009 aggiunto il secondo metodo Amazon pm't per versatilità
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)% == Sul conto 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
:: Assign Rep designator basato su QBAccount
IF / i% ($ PaymentMethod)% == Amazon Receivables SET _Rep = Amazon
:: 12-25-2009 aggiunto il secondo metodo Amazon pm't per versatilità
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)% == Sul conto SET _Rep = RB
IF / i% ($ PaymentMethod)% == Mail SET _Rep = RB
IF / i% ($ PaymentMethod)% == AMER SET _Rep = BlueZap
IF / i % ($ PaymentMethod)% == DISC SET _Rep = BlueZap
:: controlla i dati dell'indirizzo duplicato
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 Indirizzo File Scritto
: ADDRFOUND
echo rappresentante selezionato è% _Rep%
echo account selezionato è:% _QBAcct%
pause
:: RUI OUT
:: scrivi ID ordine commerciante e ID ordine RUI su RUI
:: verifica dati RUI duplicati in writeRUI.txt
cd ..
cd RegKOut
trova / i "% ($ OrderNumber)%" writeRUI.txt
echo errorlevel:% errorlevel%
if errorlevel 1 goto: RUIWRITE
if errorlevel 0 goto: IIFWRITE
: RUIWRITE
echo% ($ Invoice)% % ($ OrderNumber)% >> writeRUI.txt
:: end write RUI
:: IIF OUT
: IIFWRITE
:: Controlla i dati della fattura duplicati in writeIIF.txt
find / i "% ($ OrderNumber)%" writeIIF.txt
echo errorlevel:% errorlevel%
if errorlevel 1 goto: HEADWRITE
if errorlevel 0 goto: LINEWRITE
: HEADWRITE
:: write Dati di intestazione, spedizione / movimentazione, sconto, rappresentante e commissione nel file di importazione IIF QB
echo% ($ OrderNumber)%% ($ Purch_Date)% Fattura% ($ TransactionID)%% _QBAcct% Accounts Receivable% ($ Total)%% _Rep % >> writeIIF.txt
echo H / P% ($ Pack_Prep)% 1? >> writeIIF.txt
echo SHP% ($ spedizione)% 1? >> writeIIF.txt
echo DISC% ($ Sconto)% 1? >> writeIIF.txt
echo Comm% ($ ServiceFee)% 1? >> writeIIF.txt
: LINEWRITE
IF / i% ($ ProductIdentifier)% equ PH-1 goto WRITE_DEFA ELSE goto WRITE_DISC
echo% ($ ProductIdentifier)%
: WRITE_DISC
:: scrive prezzi scontati analizzati dalla variabile personalizzata:
echo% ($ ProductIdentifier) %% ($ Price_Each)%% ($ Quantity)%? >> writeIIF.txt
goto: EOF
: WRITE_DEFA
: scrive i prezzi predefiniti analizzati dai dati del prodotto
echo% ($ ProductIdentifier)%% ($ UnitPrice)%% ($ Quantity)%? >> writeIIF.txt
goto: EOF
:: 3 secondi di ritardo
:: TYPE NUL | CHOICE.COM / N / CY / TY, 3> NUL
: EOF


Potresti usare PowerShell per farlo? Sospetto che avrai un po 'più di controllo se usi PowerShell.
Robert Harvey,

1
Ho controllato il tuo file batch - sembra funzionare bene (dopo aver corretto la riga "shift set ($ ProductIdentifier) ​​=% ~ 9" - che, penso, è un artefatto del copiarlo e incollarlo qui).
atzz

Grazie Robert Harvey; Ho visto PowerShell. Non ho molta esperienza con la programmazione .. non sono sicuro di come sarebbe la curva di apprendimento. Ho una certa esperienza con i file batch, motivo principale per cui ho scelto questo. Ho intenzione di compilare il batch in modo che venga eseguito più velocemente. Grazie per la risposta.
BobB

Grazie atzz: da allora ho testato ancora questo file batch e sono ragionevolmente sicuro che le virgolette ~ tilde e banishing non sono correlate al problema CMD con nomi di percorso lunghi. Ho aggirato questo problema semplicemente impostando una sottodirectory con nomi brevi vicino alla radice per eliminare i nomi di percorso lunghi.
BobB

Non è necessario mostrare il file batch completo. Per favore abbrevia la tua domanda.
jor

Risposte:


193

Hai una virgoletta doppia extra alla fine, che la aggiunge di nuovo alla fine della stringa (dopo aver rimosso entrambe le virgolette dalla stringa).

Ingresso:

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

Produzione:

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

Nota: per sostituire virgolette doppie "con virgolette singole, procedi come segue:

set widget=%widget:"='%

Nota: per sostituire la parola "World" (senza distinzione tra maiuscole e minuscole) con BobB, procedi come segue:

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

Produzione:

widget="Hello BobB!"

Per quanto riguarda la tua domanda iniziale (salva il codice seguente in un file batch .cmd o .bat ed esegui):

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

Produzione:

"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 . . .

%0è il nome e il percorso dello script.
%1è il primo argomento della riga di comando e così via.


Grazie, questo era quello che stavo cercando SET BathFileAndPath=%~0(in realtà, il mio array di parametri inizia con 1, quindi ho usatoSET BathFileAndPath=%~1
Valamas

Puoi spiegare perché %widget:"=%elimina le virgolette?
CodyBugstein

4
@Imray - :old=newè una corrispondenza e una sostituzione del modello nell'espansione della variabile. Con "come il olde niente come il new, le virgolette vengono rimosse, anche se sono nel mezzo, anche se sono sbilanciate.
Jesse Chisholm

set widget =% widget: "=% ha uno strano comportamento quando il widget è vuoto, restituisce" = "
Rahul Misra

43

La tua conclusione (1) sembra sbagliata. Deve esserci qualche altro fattore in gioco.

Il problema delle virgolette nei parametri del file batch viene normalmente risolto rimuovendo le virgolette con %~e quindi rimettendole manualmente dove appropriato.

Per esempio:

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

"%cmd%" %params%

Nota le virgolette in giro %cmd%. Senza di loro, il percorso con gli spazi non funzionerà.

Se potessi pubblicare l'intero codice batch, forse potresti dare una risposta più specifica.


1
Sono d'accordo; mi sembra che il set var =% ~ 1 dovrebbe funzionare bene. Pubblicherò l'intero file batch come richiesto.
BobB

Riferimento MS: utilizzo di parametri batch . Chi sapeva che c'erano così tanti modificatori? Per riferimento, il documento ufficiale di MS fornisce la descrizione di %~1asExpands %1 and removes any surrounding quotation marks ("").
cod3monk3y

@ cod3monk3y Inoltre, è possibile chiedersi cmddi questi modificatori: call /?per aiuto sui modificatori di parametri, set /?per modificatori di variabili (probabilmente non molto intuitivi). Abbastanza utile.
atzz

12

Di solito rimuovo tutte le virgolette dalle mie variabili con:

set var=%var:"=%

E poi applicali di nuovo ovunque ne abbia bisogno, ad esempio:

echo "%var%"

All'inizio ho anche avuto problemi con questo, ho scoperto che lo vedevo :come un .- dopo averlo capito, funzionava senza intoppi. Ottimo suggerimento!
DaveU

9

Ho trascorso molto tempo cercando di farlo in modo semplice. Dopo aver esaminato attentamente il ciclo FOR, mi sono reso conto che posso farlo con una sola riga di codice:

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

Esempio:

@ECHO OFF
SET Quoted="Test string"

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

ECHO %Quoted%
ECHO %Unquoted%

Produzione:

"Test string"
Test string

Questo metodo non è rilevante se "SET Quoted = Test string". La prossima domanda è come differire "(virgolette doppie) esiste o no. A chi potrebbe interessare, grazie in
anticipo

3

Suona come un semplice bug in cui stai usando% ~ da qualche parte dove non dovresti essere. L'uso di se% ~ non cambia fondamentalmente il modo in cui funzionano i file batch, rimuove semplicemente le virgolette dalla stringa in quella singola situazione.


3

Ho imparato da questo link , se stai usando XP o superiore che funzionerà semplicemente da solo:

SET params = %~1

Non sono riuscito a far funzionare nessuna delle altre soluzioni qui su Windows 7.

Per iterare su di loro, ho fatto questo:

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

Nota: otterrai le virgolette doppie solo se passi in genere argomenti separati da uno spazio.


0
  1. set widget = "un oggetto molto utile"
  2. imposta widget
  3. widget = "un oggetto molto utile"
  4. imposta widget =% widget: "=%"
  5. imposta widget
  6. set widget = un elemento molto utile "

La citazione finale "nella riga 4 aggiunge una citazione "alla stringa. Dovrebbe essere rimosso. La sintassi per la riga 4 termina con%


@ user195488 - leggi la riga 3 come osserva che viene visualizzata:widget="a very useful item" e leggi la riga 6 come osserva che viene visualizzata:widget=a very useful item" e comprendi che la riga 7 sarebbe set widget=%widget:"=%e la riga 8 sarebbe osservare che la riga visualizzata widget=a very useful itemnon ha più una virgoletta finale .
Jesse Chisholm

0

Pensavo di avere la soluzione, ma presto ho riscontrato un comportamento insolito con l'esecuzione di file batch. Improvvisamente CMD non riconosce le dichiarazioni di percorso lungo. Esecuzione normale del file batch dal percorso completo

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

ritorna

"C: \ Documents" non è riconosciuto come comando interno o esterno ....

C'è tutto il tuo problema. CMD non riconosce gli spazi all'interno dei nomi di file dalla riga di comando, quindi pensa che tu stia tentando di passare

e Impostazioni \ Amministratore \ Documenti \ Txt \ batchtest \ dataout.bat

come parametri di

"C: \ Documents"

programma.

È necessario citarlo per eseguire un file batch con spazi nel percorso:

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

avrebbe funzionato.


0
@echo off

Setlocal enabledelayedexpansion

Set 1=%1

Set 1=!1:"=!

Echo !1!

Echo "!1!"

Set 1=

Dimostra con o senza virgolette indipendentemente dal fatto che il parametro originale contenga virgolette o meno.

E se vuoi testare l'esistenza di un parametro che può o non può essere tra virgolette, metti questa riga prima degli echi sopra:

Se '% 1' == '' vai a yoursub

Ma se si verifica l'esistenza di un file che può o non può contenere virgolette, allora è:

Se ESISTE "! 1!" goto othersub

Nota che l'uso di virgolette singole e doppie virgolette è diverso.


0

Tutte le risposte sono complete. Ma volevo aggiungere una cosa,

imposta FirstName =% ~ 1

imposta LastName =% ~ 2

Questa linea avrebbe dovuto funzionare, avevi bisogno di una piccola modifica.

imposta "FirstName =% ~ 1"

imposta "LastName =% ~ 2"

Includere il compito completo tra virgolette. Rimuoverà le virgolette senza problemi. Questo è un modo preferito di assegnazione che risolve problemi indesiderati con virgolette negli argomenti.


0

La semplice sintassi della tilde funziona solo per rimuovere le virgolette attorno ai parametri della riga di comando passati nei file batch

SET xyz=%~1

Il codice del file batch sopra imposterà xyz su qualsiasi valore venga passato come primo parametro rimuovendo le virgolette iniziali e finali (se presenti).

Ma questa semplice sintassi della tilde non funzionerà per altre variabili che non sono state passate come parametri

Per tutte le altre variabili, è necessario utilizzare la sintassi di sostituzione espansa che richiede di specificare i caratteri iniziali e in ritardo da rimuovere. In effetti stiamo istruendo a rimuovere il primo e l'ultimo personaggio senza guardare cosa sia effettivamente.

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

Se volessimo controllare quale fosse la citazione del primo e dell'ultimo carattere prima di rimuoverlo, avremo bisogno di un codice aggiuntivo come segue

@SET VAR="Some Very Long Quoted String"
If aa%VAR:~0,1%%VAR:~-1%aa == aa""aa SET UNQUOTEDVAR=%VAR:~1,-1%
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.