在過去的 12 年里,我一直在 Linux 中作業,在此之前使用過 Windows 和命令列,并且最近不得不恢復那些批處理檔案技能,以獲得一些易于使用/編輯的實用程式。但是,我在找出如何使用換行符構建字串變數時遇到了一些問題(相當于 Linux 的echo -e "Line1\nLine2")
基本上,我的實用程式會詢問用戶的三個問題并檢查輸入的有效性。如果有效性失敗,每個輸入都有一個稍微不同的“錯誤訊息”。然后我檢查errMsg變數是否包含任何內容,如果包含,它會列出來自 3 個有效性檢查的整理錯誤訊息。除了錯誤訊息在一行之外,這一切都完美無缺,我想將每個錯誤放在它自己的行上。然后我“僅僅”在字串中添加換行符......這就是這個問題的癥結所在。
我已將此鏈接用作參考點,并使用基本字串,新行按預期顯示。但是,當我使用變數時,不會出現新行,我希望有人可以向我解釋原因。
我有以下代碼片段
@echo off
setlocal enableextensions enabledelayedexpansion
set \n=^
set NL=^^^%\n%%\n%^%\n%%\n%
echo This does indeed put in a newline%NL%and this is the 2nd line
:: output follows:
::This does indeed put in a newline
::and this is the 2nd line
set var=Line1%NL%
set var=%var%Line2%NL%
:: output follows:
::Line1Line2
set errMsg=This would be the first custom error message%NL%
set errMsg=%errMsg%This would be the second custom error message%NL%
set errMsg=%errMsg%This would be the third custom error message%NL%
:: output follows
::This would be the first custom error messageThis would be the third custom error message
顯然,此時我希望 Line1Line2 示例分成兩行,然后最后一個示例將所有自定義錯誤訊息分成三行(而實際上,它也缺少第二條/中間錯誤訊息)
誰能向我解釋為什么這沒有按預期作業?我想知道它是否與延遲擴展有關(我相信我需要:這個片段是確實需要延遲擴展的較長檔案的一部分)。有沒有更好(或僅僅是替代)的方式來完成我正在尋找的東西?!
uj5u.com熱心網友回復:
創建一個新的行變數是一個好的開始。但是你應該以不同的方式使用它。
百分比擴展不適用于變數中的換行符,它可以完成,但它非常復雜。
但延遲擴展完美適用于任何角色
@echo off
setlocal EnableDelayedExpansion
(set \n=^
%=empty line=%
)
echo Line1!\n!Line2
set "multiline_var=First Line!\n!Second Line"
echo !multiline_var!
uj5u.com熱心網友回復:
首先,延遲擴展不會影響立即擴展的換行符(或正確說的換行符),因為您使用的是立即 ( %-) 擴展。
主要問題是%- 擴展發生得太早,當變數包含換行符時,這似乎會干擾對換行符的識別。
每次決議器擴展%包含換行符的 -variable 時,換行符后面的所有內容都會被忽略,因此必須對它們進行轉義,從而導致多種轉義序列。這可以通過以下腳本來演示:
@echo off
setlocal EnableExtensions EnableDelayedExpansion
rem // Define a line-feed character:
set \n=^
rem // Define an escaped line-feed character:
set NL=^^^%\n%%\n%^%\n%%\n%
::rem // Redefine the escaped new-line character; it does not change, because the parser first expands `%`-variables before it recognises line-breaks in them:
::set NL=^^%NL%%NL%
rem // Define multi-escaped sequences needed when the same expanded value passes through the parser several times:
set NLNL=^^^^^^^^^^^^^^%NL%%NL%^^%NL%%NL%^^^^^^%NL%%NL%^^%NL%%NL%
set NLNLNL=^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^%NL%%NL%^^%NL%%NL%^^^^^^%NL%%NL%^^%NL%%NL%^^^^^^^^^^^^^^%NL%%NL%^^%NL%%NL%^^^^^^%NL%%NL%^^%NL%%NL%
::set NLNLNL=^^^^^^^^^^^^^^^^^^^^^^^^%NLNL%%NLNL%^^^^^^^^%NLNL%%NLNL%
echo ---- DEFINITION ----
set NL
echo --------------------
echo !\n! ***** IMMEDIATE EXPANSION ***** !\n!
rem // The more parser passes the more escaping is needed:
echo -- VARIABLE CHECK --
set errMsg=This would be the first custom error message%NLNLNL%
set errMsg
set errMsg=%errMsg%This would be the second custom error message%NLNL%
set errMsg
set errMsg=%errMsg%This would be the third custom error message%NL%
set errMsg
echo -- MESSAGE OUTPUT --
echo %errMsg%
echo --------------------
echo !\n! ***** `CALL` EXPANSION ***** !\n!
echo -- VARIABLE CHECK --
set errMsg=This would be the first custom error message%%NL%%
set errMsg
set errMsg=%errMsg%This would be the second custom error message%%NL%%
set errMsg
set errMsg=%errMsg%This would be the third custom error message%%NL%%
set errMsg
echo -- MESSAGE OUTPUT --
call echo %errMsg%
echo --------------------
echo !\n! ***** DELAYED EXPANSION ***** !\n!
echo -- VARIABLE CHECK --
set errMsg=This would be the first custom error message!\n!
set errMsg
set errMsg=!errMsg!This would be the second custom error message!\n!
set errMsg
set errMsg=!errMsg!This would be the third custom error message!\n!
set errMsg
echo -- MESSAGE OUTPUT --
echo !errMsg!
echo --------------------
endlocal
exit /B
這是相關的命令提示符輸出:
---- DEFINITION ---- NL=^ NLNL=^^^^^^^ ^ ^^^ ^ NLNLNL=^^^^^^^^^^^^^^^ ^ ^^^ ^ ^^^^^^^ ^ ^^^ ^ -------------------- ***** IMMEDIATE EXPANSION ***** -- VARIABLE CHECK -- errMsg=This would be the first custom error message^^^^^^^ ^ ^^^ ^ errMsg=This would be the first custom error message^^^ ^ This would be the second custom error message^^^ ^ errMsg=This would be the first custom error message^ This would be the second custom error message^ This would be the third custom error message -- MESSAGE OUTPUT -- This would be the first custom error message This would be the second custom error message This would be the third custom error message -------------------- ***** `CALL` EXPANSION ***** -- VARIABLE CHECK -- errMsg=This would be the first custom error message%NL% errMsg=This would be the first custom error message%NL%This would be the second custom error message%NL% errMsg=This would be the first custom error message%NL%This would be the second custom error message%NL%This would be the third custom error message%NL% -- MESSAGE OUTPUT -- This would be the first custom error message This would be the second custom error message This would be the third custom error message -------------------- ***** DELAYED EXPANSION ***** -- VARIABLE CHECK -- errMsg=This would be the first custom error message errMsg=This would be the first custom error message This would be the second custom error message errMsg=This would be the first custom error message This would be the second custom error message This would be the third custom error message -- MESSAGE OUTPUT -- This would be the first custom error message This would be the second custom error message This would be the third custom error message --------------------
在該IMMEDIATE EXPANSION部分中,當命令列多次通過決議程序時,需要復雜的轉義序列來維護換行符。
本節說明了一種更簡單的方法,使用CALL EXPANSIONcall命令,該命令引入了另一個決議階段,它可以擴展文字字串部分%NL%,它實際上包含在errMsg變數中而不是換行符中。請注意,這call很慢并且有副作用,例如插入符號-(^-)加倍和丟失&, |,<以及>在某些情況下。
最好的選擇當然是使用延遲擴展,如本DELAYED EXPANSION節所示,因為這允許變數errMsg實際包含換行符并安全地擴展它們而不會被決議器過早識別。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/420399.html
標籤:
上一篇:批處理檔案過濾器回圈輸出
