Toplu iş dosyasındaki değişkenlerden çift tırnakların kaldırılması CMD ortamında sorunlar yaratır


117

Toplu değişkenlerden alıntıları kaldırmanın etkili ve güvenli bir yolu olan var mı?

% 1,% 2,% 3 vb. Parametrelerin bir listesini başarıyla içe aktaran ve bunları adlandırılmış değişkenlere yerleştiren bir toplu iş dosyası yazdım. Bu parametrelerin bazıları birden çok kelime içerir ve bu nedenle çift tırnak içine alınır.

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

Bu% değişkenler, daha sonra adlandırılmış değişkenlere yerleştirilir:

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

değişkenlerin doğrulanması yankı ile yapılır.

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

sonuçlar şu şekilde görüntülenir

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

Seçili değişkenlere dahil edilen alıntıları kaldırmam gerekiyor. Örneğin, FirstName ve LastName başka yerlerde kullanılır ve tırnak işareti içermemelidir.

Bir test toplu iş dosyasında, değişkenlerde ~ tilde karakterini kullanarak tırnak işaretlerini ortadan kaldırmayı başardım.

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

Çözüme sahip olduğumu düşündüm, ancak kısa süre sonra toplu iş dosyalarının yürütülmesiyle ilgili olağandışı davranışlarla karşılaştım. Birden CMD, uzun yol durumlarını tanımıyor. Toplu iş dosyasının tam yoldan normal yürütülmesi

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

İadeler

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

Bu nedenle, gelen% 1% 2 ...% n değişkenlerine ~ tilde karakterinin eklenmesi bazı değişikliklere neden olmuş gibi görünüyor. Muhtemelen bazı ortam değişkenleri değiştirildi?

Ayrıca, FOR komutunu kullanarak çeşitli denemelerle değişken içerisinden alıntıları silmeyi denedim. Bu garip görünüyor ve görevi gerçekleştirmek için bir değişken listesi oluşturarak bunu nasıl başaracağımı öğrenemedim:

bunun gibi bir şey:

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

Sanırım iki sorunum var.

1) Gelen% 1% 2 değişkenlerine (% ~ 1, vb.) ~ Tilde ekleme konusundaki 'kısa ve öz' fikrim, bazı ayarları etkilemiş ve CMD'nin uzun yol adlarında gezinme şeklini değiştirmiş gibi görünüyor.

2) Seçili adlandırılmış değişkenlerden alıntıları elemek için hala temiz ve kolay bir yol arıyorum.

Daha deneyimli olanlar için herhangi bir yardım çok takdir edilecektir. Burada becerilerimin sonuna geldim ... biraz rehberliğe ihtiyacım var lütfen!

12/26/2009 13:36 PST toplu iş dosyasının tamamını düzenle:

Blockquote
:: dataout.bat
:: revizyon 12/25/2009 gömülü "tırnak işaretlerini ortadan kaldırmak için gelen% değişkenlere ~ tilde ekleyin.
:: adres listesini komut satırı parametrelerini kullanarak
yazar :: QBooks IIF için veri çıktı listesini
yazar import :: writees RUI
:: için Satıcı Sipariş verileri
:: listmail [ad] [soyad] ["adres dizesi"] ["şehir dizesi"] [eyalet] [posta kodu] [Sipariş #] [Satın AlmaTarihi] [Kayıt adı] ["FirstName LastName"] [TransactionID] [PaymentMethod] [Toplam] [ProductID] [Qty] [Price_Each] [PackPrep] [Shipping] [CommissionPmt] [Fatura #]
:: örnek: dataout Bellewinkle Moose "123 Green Forest Way" "Vancouver" WA 98664 1004968 05/25/2009 "Bellewinkle Moose" "Olive Oyl" 101738 "Hesapta" 20.67 FK-1P 1 8.95 3.00 1.39 239
@echo off
cls
c:
cd \
cd belgeleri ve ayarlar \ yönetici \ belgelerim \ txt \ batchtest
echo işleme% 1% 2
: VARISET
::% N komut satırı parametrelerini dizi değişkenlerine dönüştür
($ Ad) =% ~ 1
set ($ Soyadı) =% ~ 2
set ($ BillingAddress1) =% ~ 3
set ($ BillingCity) =% ~ 4
set ($ BillingState) =% ~ 5
set ($ BillingPostal) =% ~ 6
set ($ OrderNumber) =% ~ 7
set ($ Purch_Date) =% ~ 8
set ($ RegistrationName) =% ~ 9
vardiya
seti ($ İşlem Kimliği ) =% ~ 9
vardiya
seti ($ Ödeme Yöntemi) =% ~ 9
vardiya
seti ($ Toplam) =% ~ 9
vardiya seti ($ Ürün Kimliği) =% ~ 9
vardiya
seti ($ Miktar) =% ~ 9
vardiya
seti ($ Price_Each) =% ~ 9
vardiya
seti ($ Pack_Prep) =% ~ 9
vardiya
seti ($ Nakliye) =% ~ 9
vardiya
seti ($ Servis Ücreti) =% ~ 9
vardiya
seti ($ İndirim) =% ~ 9
vardiya
kümesi ($ Fatura) =% ~ 9
vardiya
kümesi ($
UnitPrice ) =% ~ 9 set _hipCombName =% ($ FirstName)%% ($ Soyadı)%
echo gemi birleşik adı% _ShipCombName%
pause
:: logfile
echo FN% ($ FirstName)% LN% ($ Soyadı)% BA% ($ BillingAddress1)%% ($ BillingCity)%% ($ BillingState)%% ($ BillingPostal)%% ($ dize değişkenlerini yaz OrderNumber)%% ($ Purch_Date)%% ($ RegistrationName)%% ($ TransactionID)% ($ PaymentMethod)%% ($ Toplam)%% ($ ProductIdentifier)%% ($ Miktar)%% ($ Price_Each) %% ($ Pack_Prep)% ($ Shipping)%% ($ ServiceFee)%% ($ İndirim)% ($ Invoice)% ($ UnitPrice)%% _ShipCombName% >> d_out_log.txt
:: Hesap atama ölçütü Servis Sağlayıcı
IF / i% ($ PaymentMethod)% == Amazon Receivables SET _QBAcct = Amazon.com
:: 12-25-2009, çok yönlülük için ikinci Amazon pm't yöntemini ekledi
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)% == Hesapta 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
:: QBAccount
IF / i% ($ PaymentMethod)% == Amazon Alacakları SET _Rep = Amazon
:: 12-25-2009, çok yönlülük için ikinci Amazon pm't yöntemini ekledi
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)% == Hesapta SET _Rep = RB
IF / i% ($ PaymentMethod)% == Mail SET _Rep = RB
IF / i% ($ PaymentMethod)% == AMER SET _Rep = BlueZap
IF / i % ($ PaymentMethod)% == DISC SET _Rep = BlueZap
:: yinelenen adres verilerini kontrol et
findstr / i / s "% _ShipCombName%" addrlist.txt
echo errorlevel:% errorlevel%
if errorlevel 1 goto:
errorlevel 0 ise ADDRWRITE : ADDRFOUND
: ADDRWRITE
echo% _ShipCombName% >> addrlist.txt
echo% ($ BillingAddress1)% >> addrlist.txt
echo% ($ BillingCity)% ($ BillingState)%% ($ BillingPostal)% >> addrlist.txt
echo. >> addrlist.txt
echo Yazılan Adres Dosyası
: ADDRFOUND
echo seçilen temsilci% _Rep%
echo seçilen hesap:% _QBAcct%
pause
:: RUI OUT
:: Satıcı Sipariş Kimliğini ve RUI Sipariş Kimliğini RUI'ye yazın
:: yinelenen RUI verilerini kontrol edin writeRUI.txt
cd ..
cd RegKOut
find / i "% ($ OrderNumber)%" writeRUI.txt
echo errorlevel:% errorlevel%
if errorlevel 1 goto: RUIWRITE
eğer errorlevel 0 goto: IIFWRITE
: RUIWRITE
echo% ($ Invoice)% % ($ OrderNumber)% >> writeRUI.txt
:: end write RUI
:: IIF OUT
: IIFWRITE
:: writeIIF.txt dosyasında yinelenen fatura verilerini kontrol edin
find / i "% ($ OrderNumber)%" writeIIF.txt
echo errorlevel:% errorlevel%
if errorlevel 1 goto: HEADWRITE
eğer errorlevel 0 goto: LINEWRITE
: HEADWRITE
:: write Başlık, Sevkiyat / İşleme, indirim, Temsilci ve komisyon verilerini QB IIF'ye içe aktarma dosyası
yankısı% ($ Sipariş Numarası)%% ($ Satın Alma_tarihi)% Fatura% ($ İşlem Kimliği)%% _QBAcct% Alacak Hesapları% ($ Toplam)%% _Rep % >> writeIIF.txt
echo H / P% ($ Pack_Prep)% 1? >> writeIIF.txt
echo SHP% ($ Nakliye)% 1? >> writeIIF.txt
echo DISC% ($ İndirim)% 1? >> writeIIF.txt
echo Comm% ($ ServiceFee)% 1? >> writeIIF.txt
: LINEWRITE
IF / i% ($ ProductIdentifier)% equ PH-1 goto WRITE_DEFA ELSE git WRITE_DISC
echo% ($ ProductIdentifier)%
: WRITE_DISC
:: özel değişkenden ayrıştırılan indirimli fiyatları yazar:
echo% ($ ProductIdentifier) %% ($ Price_Each)%% ($ Miktar)%? >> writeIIF.txt
goto: EOF
: WRITE_DEFA
: Ürün verilerinden ayrıştırılan varsayılan fiyatları yazar
echo% ($ ProductIdentifier) %% ($ UnitPrice)%% ($ Quantity)%? >> writeIIF.txt
goto: EOF
:: 3-saniye gecikme
:: TYPE NUL | CHOICE.COM / N / CY / TY, 3> NUL
: EOF


Bunu yapmak için PowerShell'i kullanabilir misiniz? PowerShell'i kullanırsanız biraz daha kontrol sahibi olacağınızdan şüpheleniyorum.
Robert Harvey

1
Toplu iş dosyanızı kontrol ettim - düzgün çalışıyor gibi görünüyor ("shift set ($ ProductIdentifier) ​​=% ~ 9" satırını düzelttikten sonra - ki bu, onu buraya kopyalayıp yapıştırmanın bir ürünüdür).
atzz

Teşekkürler Robert Harvey; PowerShell'e bakıyorum. Programlama konusunda pek tecrübeli değilim .. öğrenme eğrisinin nasıl olacağından emin değilim. Toplu iş dosyalarıyla ilgili bazı deneyimlerim var, bunu seçmemin ana nedeni. Daha hızlı çalışması için toplu işi derlemeye niyetliyim. Cevap için teşekkürler.
BobB

Teşekkürler atzz: O zamandan beri bu toplu iş dosyasını biraz daha test ettim ve ~ tilde ve banishing alıntılarının CMD problemi w / long pathnames ile ilgisiz olduğundan makul ölçüde eminim. Uzun yol adlarını ortadan kaldırmak için köke yakın kısa adlı bir alt dizin oluşturarak bunun üstesinden geldim.
BobB

Tam toplu iş dosyasını göstermeye gerek yok. Lütfen sorunuzu kısaltın.
jor

Yanıtlar:


193

Sonunda, onu dizenin sonuna ekleyen fazladan bir çift tırnak var (dizeden her iki tırnağı da kaldırdıktan sonra).

Giriş:

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

Çıktı:

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

Not: Çift Tırnağı "Tek Tırnaklar" ile değiştirmek için aşağıdakileri yapın:

set widget=%widget:"='%

Not: "Dünya" kelimesini (büyük / küçük harfe duyarlı değil) BobB ile değiştirmek için aşağıdakileri yapın:

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

Çıktı:

widget="Hello BobB!"

İlk sorunuza gelince (aşağıdaki kodu bir .cmd veya .bat toplu iş dosyasına kaydedin ve çalıştırın):

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

Çıktı:

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

%0Komut Dosyası Adı ve Yoludur.
%1ilk komut satırı argümanıdır ve bu böyle devam eder.


Teşekkürler, peşinde olduğum şey buydu SET BathFileAndPath=%~0(aslında, param dizim 1 ile başlıyor, bu yüzden kullandımSET BathFileAndPath=%~1
Valamas

%widget:"=%Tırnak işaretlerinden neden kurtulduğunu açıklayabilir misiniz ?
CodyBugstein

4
@Imray - :old=newdeğişken genişletmede bir desen eşleşmesi ve değiştirmedir. İle "olarak oldolarak ve hiçbir şey new, tırnak onlar dengesiz olsa bile ortada olsa bile kaldırılır.
Jesse Chisholm

set widget =% widget: "=%, widget boşken garip bir davranış sergiliyor," = "döndürüyor
Rahul Misra

43

Sonucunuz (1) kulağa yanlış geliyor. Oyunda başka bir faktör olmalı.

Toplu iş dosyası parametrelerindeki alıntı sorunu, normalde ile tırnak işaretlerini kaldırarak %~ve ardından bunları uygun olduğu yerde manuel olarak geri koyarak çözülür .

Örneğin:

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

"%cmd%" %params%

Alıntılara dikkat edin %cmd%. Onlar olmadan boşluklu yol çalışmaz.

Toplu kodunuzun tamamını gönderebilirseniz, belki daha spesifik yanıtlar verilebilir.


1
Katılıyorum; bana öyle geliyor ki var =% ~ 1 seti gayet iyi çalışmalı. Toplu iş dosyasının tamamını istendiği gibi göndereceğim.
BobB

MS Referansı: Toplu iş parametrelerini kullanma . Bu kadar çok değiştirici olduğunu kim bilebilirdi? Başvuru için, resmi MS doc açıklamasını verir %~1olarakExpands %1 and removes any surrounding quotation marks ("").
cod3monk3y

@ cod3monk3y Ayrıca, cmdkendine bu değiştiriciler hakkında soru sormak da mümkündür : call /?parametre değiştiricilerle ilgili yardım için, set /?değişken değiştiriciler için (muhtemelen pek sezgisel değildir). Oldukça kullanışlı.
atzz

12

Genellikle tüm alıntıları değişkenlerimden kaldırırım:

set var=%var:"=%

Ve sonra ihtiyaç duyduğum her yerde tekrar uygulayın, örneğin:

echo "%var%"

Ayrıca, ilk başta bu sorun vardı görüştüğüm çıktı :bir şekilde .- bir aksaklık çalıştı out, endam sonra. Harika bir ipucu!
DaveU

9

Bunu basit bir şekilde yapmaya çalışırken çok zaman harcadım. FOR döngüsüne dikkatlice baktıktan sonra, bunu sadece bir satır kodla yapabileceğimi fark ettim:

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

Misal:

@ECHO OFF
SET Quoted="Test string"

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

ECHO %Quoted%
ECHO %Unquoted%

Çıktı:

"Test string"
Test string

Bu yöntem, "SET Quoted = Test string" iken geçerli değildir. Bir sonraki soru, nasıl farklılaşılacağıdır "(çift alıntı) var mı yok mu? Kimin
ilgisini çekebilir, şimdiden

3

Bu, olmamanız gereken bir yerde% ~ kullandığınız basit bir hataya benziyor. % ~ Kullanımı, toplu iş dosyalarının çalışma şeklini temelden değiştirmez, yalnızca bu durumda dizeden tırnak işaretlerini kaldırır.


3

Bu bağlantıdan öğrendim , eğer XP veya üstü kullanıyorsanız, bunun kendi başına çalışacağını:

SET params = %~1

Windows 7'de çalışmak için buradaki diğer çözümlerden hiçbirini alamadım.

Onları tekrarlamak için şunu yaptım:

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

Not: Yalnızca bir boşlukla ayrılmış bağımsız değişkenler girerseniz çift tırnak alırsınız.


0
  1. set widget = "çok kullanışlı bir öğe"
  2. widget ayarla
  3. widget = "çok kullanışlı bir öğe"
  4. widget =% widget'ı ayarla: "=%"
  5. widget ayarla
  6. set widget = çok kullanışlı bir öğe "

"4. satırdaki sondaki alıntı ", dizeye bir alıntı ekliyor . Kaldırılmalıdır. 4. satırın sözdizimi şu şekilde biter:%


@ user195488 - görüntülendiğini gözlemleyerekwidget="a very useful item" 3. satırı okuyun : ve görüntülendiğini gözlemledikçewidget=a very useful item" 6. satırı okuyun : 7. satırın olacağını set widget=%widget:"=%ve 8. satırın görüntülenen satırın widget=a very useful itemartık sonunda bir tırnağa sahip olmadığını gözlemleyeceğini anlayın .
Jesse Chisholm

0

Çözüme sahip olduğumu düşündüm, ancak kısa süre sonra toplu iş dosyalarının yürütülmesiyle ilgili olağandışı davranışlarla karşılaştım. Birden CMD, uzun yol durumlarını tanımıyor. Toplu iş dosyasının tam yoldan normal yürütülmesi

C: \ Documents and Settings \ Yönetici \ Belgelerim \ Txt \ batchtest \ dataout.bat

İadeler

'C: \ Documents' dahili veya harici bir komut olarak tanınmıyor ....

Senin sorunun var. CMD, komut satırındaki dosya adlarının içindeki boşlukları anlamıyor, bu yüzden geçmeye çalıştığınızı düşünüyor

ve Ayarlar \ Yönetici \ Belgelerim \ Txt \ batchtest \ dataout.bat

parametreler olarak

"C: \ Documents"

programı.

Yolda boşluklar olan bir toplu iş dosyasını çalıştırmak için alıntı yapmanız gerekir:

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

işe yarardı.


0
@echo off

Setlocal enabledelayedexpansion

Set 1=%1

Set 1=!1:"=!

Echo !1!

Echo "!1!"

Set 1=

Orijinal parametrenin tırnak işareti olup olmadığına bakılmaksızın tırnak işaretli veya tırnaksız gösterir.

Ve tırnak içinde olabilecek veya olmayabilecek bir parametrenin varlığını test etmek istiyorsanız, bu satırı yukarıdaki yankıların önüne koyun:

'% 1' == '' ise alt sitenize gidin

Ancak, tırnak işaretleri olan veya olmayan bir dosyanın varlığını kontrol ediyorsanız:

VAR ise "! 1!" başkalarına git

Tek tırnak ve çift tırnak kullanımının farklı olduğunu unutmayın.


0

Tüm cevaplar tamamlandı. Ama bir şey eklemek istedim,

Ad =% ~ 1 olarak ayarlayın

Soyadı =% ~ 2 olarak ayarla

Bu hat işe yaramalıydı, küçük bir değişikliğe ihtiyacın vardı.

"Ad =% ~ 1" olarak ayarlayın

"Soyad =% ~ 2" olarak ayarlayın

Tüm ödevi tekliflere dahil edin. Teklifleri sorunsuz bir şekilde kaldıracaktır. Bu, bağımsız değişkenlerdeki alıntılarla ilgili istenmeyen sorunları düzelten tercih edilen bir atama yöntemidir.


0

Basit yaklaşık işareti sözdizimi yalnızca toplu iş dosyalarına iletilen komut satırı parametrelerinin etrafındaki tırnak işaretlerini kaldırmak için çalışır.

SET xyz=%~1

Yukarıdaki toplu iş dosyası kodu, xyz'yi ilk parametre olarak, baştaki ve sondaki teklifleri (varsa) ayırarak geçirilen değere ayarlayacaktır.

Ancak, bu basit yaklaşık işareti sözdizimi, parametre olarak aktarılmayan diğer değişkenler için çalışmayacaktır.

Diğer tüm değişkenler için, kaldırılacak baştaki ve geride kalan karakterleri belirlemenizi gerektiren genişletilmiş ikame sözdizimi kullanmanız gerekir. Etkili bir şekilde, ilk ve son karakteri, gerçekte ne olduğuna bakmadan kaldırmamız için talimat veriyoruz.

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

Kaldırmadan önce ilk ve son karakterin gerçekte ne olduğunu kontrol etmek istersek, aşağıdaki gibi bazı ekstra koda ihtiyacımız olacaktır.

@SET VAR="Some Very Long Quoted String"
If aa%VAR:~0,1%%VAR:~-1%aa == aa""aa SET UNQUOTEDVAR=%VAR:~1,-1%
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.