2012-03-18 21 views
5

मैं एक चर में संग्रहीत एक स्ट्रिंग गूंजने की कोशिश कर रहा हूं लेकिन ऐसा लगता है कि इसमें बहुत से भागने की आवश्यकता है। मैं निम्नलिखित कोड के साथ कोशिश कर रहा हूँ:विंडोज बैच फ़ाइल में सटीक स्ट्रिंग इको?

setlocal EnableDelayedExpansion 
@echo off 
set "[email protected]##&!$^&%**(&)" 
echo !grass! 

मैं चर grass गूंज करना चाहते शब्दशः तो मैं उत्पादन में एक @##&!$^&%**(&) देखते हैं। क्या किया जाए? धन्यवाद!

उत्तर

12

echo !grass! हमेशा किसी भी भागने की आवश्यकता के बिना वर्तमान मूल्य क्रियापद को प्रतिबिंबित करेगा। आपकी समस्या यह है कि मूल्य वह नहीं है जो आपको लगता है! समस्या तब होती है जब आप मान सेट करने का प्रयास कर रहे होते हैं।

सही एस्केप अनुक्रम अपने मान सेट करने के

set "[email protected]##&^!$^^&%%**(&)" 

और अब स्पष्टीकरण के लिए है। आपको जो जानकारी चाहिए उसे How does the Windows Command Interpreter (CMD.EXE) parse scripts? में दफनाया गया है। लेकिन यह पालन करना थोड़ा मुश्किल है।

1) % हर बार लाइन पार्स किया जाएगा के लिए %% के रूप में भाग निकले किया जाना चाहिए:

आप दो समस्याएं हैं। उद्धरणों की उपस्थिति या अनुपस्थिति में कोई फर्क नहीं पड़ता है। देरी विस्तार राज्य भी कोई फर्क नहीं पड़ता।

set pct=% 
:: pct is undefined 

set pct=%% 
:: pct=% 

call set pct=%% 
:: pct is undefined because the line is parsed twice due to CALL 

call set pct=%%%% 
:: pct=% 

2) एक ! शाब्दिक ^! के रूप में जब भी यह पार्सर की देरी विस्तार चरण से पार्स किया गया है भाग निकले किया जाना चाहिए। यदि किसी लाइन में ! देरी के विस्तार के दौरान इसके भीतर कहीं भी है, तो ^ शाब्दिक ^^ से बच जाना चाहिए। लेकिन ^ को पार्सर के विशेष चरित्र चरण के लिए या तो ^^ के रूप में उद्धृत या भाग लिया जाना चाहिए। यह इस तथ्य से और जटिल हो सकता है कि एक कॉल ^ वर्णों को दोगुना कर देगा। (क्षमा करें, यह समस्या का वर्णन करने के लिए बहुत मुश्किल है, और पार्सर जटिल है!)

setlocal disableDelayedExpansion 

set test=^^ 
:: test=^ 

set "test=^" 
:: test=^ 

call set test=^^ 
:: test=^ 
:: 1st pass - ^^ becomes^
:: CALL doubles ^, so we are back to ^^ 
:: 2nd pass - ^^ becomes^

call set "test=^" 
:: test=^^ because of CALL doubling. There is nothing that can prevent this. 

set "test=^...!" 
:: test=^...! 
:: ! has no impact on^when delayed expansion is disabled 

setlocal enableDelayedExpansion 

set "test=^" 
:: test=^ 
:: There is no ! on the line, so no need to escape the quoted ^. 

set "test=^!" 
:: test=! 

set test=^^! 
:: test=! 
:: ! must be escaped, and then the unquoted escape must be escaped 

set var=hello 
set "test=!var! ^^ ^!" 
:: test=hello^! 
:: quoted^literal must be escaped because ! appears in line 

set test=!var! ^^^^ ^^! 
:: test=hello^! 
:: The unquoted escape for the^literal must itself be escaped 
:: The same is true for the ! literal 

call set test=!var! ^^^^ ^^! 
:: test=hello^! 
:: Delayed expansion phase occurs in the 1st pass only 
:: CALL doubling protects the unquoted^literal in the 2nd pass 

call set "test=!var! ^^ ^!" 
:: test=hello ^^ ! 
:: Again, there is no way to prevent the doubling of the quoted^literal 
:: when it is passed through CALL 
+0

अच्छा स्पष्टीकरण। धन्यवाद! – user1077213

+0

क्या वहां वर्णों की एक सूची है जो भागने की आवश्यकता है? जैसे कि '*', '(' आदि? – user1077213

2

dbenham के रूप में कहा, यह केवल काम है।
आप डबेंहम जैसे भागने का उपयोग कर सकते हैं, यह आवश्यक है कि जब आप मान सेट करते हैं तो EnableDelayedExpansion सक्रिय है।
इसलिए आपको विस्मयादिबोधक चिह्न से बचने की जरूरत है और लाइन में एक विस्मयादिबोधक चिह्न होने पर कैरेट से बच जाना चाहिए, उद्धरण उस स्थिति में बेकार हैं।
लेकिन आप को से पहले मान भी सेट कर सकते हैं, आप EnableDelayedExpansion,
सक्रिय करते हैं तो आपको कैरेट की आवश्यकता नहीं थी।

+0

तो उदाहरण के लिए, '@ ## &! $^और% ** (&)' से बचने का तरीका कैसा दिखता है जैसे आप देरी विस्तार को सक्षम करने से पहले मान सेट करते हैं – user1077213

+2

@ user1077213 - जब तक मूल्य उद्धृत किया जाता है, तब केवल% को दोगुना करने की आवश्यकता होती है: 'सेट "घास = @ ## &! $^और %% ** (&)" 'उद्धरण के बिना आपको कई भाग निकलते हैं: 'सेट घास = @ ##^&! $ ^^^ और %% ** (^ &)' तब तक काम करेगा जब तक कि एक कोष्ठक ब्लॉक में नहीं है। यदि ब्रांड्स सक्रिय हैं, तो समापन ') 'भी बच जाना चाहिए:' घास सेट करें = @ ##^और! $ ^^^ और %% ** (^ और ^) '। – dbenham

+0

यह समझ में आता है। धन्यवाद! :) – user1077213

संबंधित मुद्दे