我编写了以下宏,我希望该宏将表的原始数据返回到底部,引用执行脚本的电脑的主机名,但它不起作用。 宏定义中的语法似乎有一些错误。 事实上,@echo on 将会返回:
E:\BATCH\prova_token>(
set "par.!I!=!scriptPath!"
set /a "I+=1"
)
!par.1! eol=; tokens=1,2,3,4 delims=," not expected.
E:\BATCH\prova_token>echo
ECHO active.
有人可以帮助我吗?
@echo on
:: Define LF as a Line Feed (newline) string
set LF=^
::Above 2 blank lines are required - do not remove
::define a newline with line continuation
:: set ^"\n=^^^%LF%%LF%^%LF%%LF%^^" this is an old style and more complex \n definition
:: Next is the modern style \n definition
(set \n=^^^
%=EMPTY=%
)
set HOSTN=%COMPUTERNAME%
for /f "delims=:" %%N in ('findstr /nlbc:":: Begin Host-Pos list " "%~f0"') do set /a "beginHPL=%%N"
for /f "delims=:" %%N in ('findstr /nlbc:":: End Host-Pos list " "%~f0"') do set /a "endHPL=%%N"
set @{selectPos}=for %%. in (1 2) do if %%.==2 (for %%L in ("!LF!") DO (%\n%
set /a "I=1"%\n%
for /f "tokens=* delims=" %%1 in ("!args: =%%~L!") do (%\n%
set "par.!I!=!%%~1!"%\n%
set /a "I+=1"%\n%
)%\n%
%= Inizio della vera macro =%%\n%
set /a "count=!par.1!+1"%\n%
for /F "usebackq skip=!par.1! eol=; tokens=1,2,3,4 delims=," %%M IN (%~f0) DO (%\n%
if %%M == !par.3! (%\n%
endlocal^& (%\n%
set pos.1=%%~M%\n%
set pos.2=%%~N%\n%
set pos.3=%%~O%\n%
set pos.4=%%~P%\n%
break%\n%
)%\n%
)%\n%
set /a "count+=1"%\n%
)%\n%
%= Fine macro =%%\n%
)) else setlocal EnableDelayedExpansion ^& set args=
%@{selectPos}% beginHPL endHPL HOSTN scriptPath
echo %pos.1% %pos.2% %pos.3% %pos.4%
:ESCI
exit /b 1000
:: Begin Host-Pos list {
;Values in the first token must be unique!!!
PRM014BBIBL04,BIBLIOTECA01,192.168.14.55,02220195
WIN030XELETT10,COMUNE01,192.168.30.101,02220168
PRM021ASPEU01,DIGIPASS01,192.168.21.142,02220917
; questa è una riga di commento e viene ignorata
:: End Host-Pos list }
最佳答案
endlocal ^& set "POS=%P%"%\n%
无法工作,因为百分比扩展在宏内部不起作用,因为宏本身已经通过百分比扩展进行了扩展.
改用 FOR block 。
for /F %%V in ("!P!") do ( %\n%
endlocal %\n%
set "POS=%%V" %\n%
) %\n%
顺便说一句。您的评论风格:
if 1==2 ( comment ) %\n%
它有效,但注释是宏的一部分。
宏中的常用样式
是:
%= comment =% %\n%
它还允许在注释中使用特殊字符,并且注释本身会在宏的定义阶段被删除。
编辑后:
这可能是一个合理的宏
@echo off
(set LF=^
%=EMPTY=%
)
::define a newline with line continuation
:: Next is the modern style \n definition
(set \n=^^^
%=EMPTY=%
)
set "HOSTN=WIN030XELETT10"
set @{selezionaPOS}=for %%. in (1 2) do if %%.==2 (for %%L in ("!LF!") DO ( %\n%
%= Fetching arguments =% %\n%
for /f "tokens=1,*" %%1 in ("!args!") do ( %\n%
set "par.host=%%~1" %\n%
set "par.listname=%%~2" %\n%
)%\n%
%=DEBUG=% set "par." %\n%
%= Search for par.host in the list =% %\n%
set "inside_list=0" %\n%
set "found_result=" %\n%
for /F "usebackq eol=; tokens=1,* delims=," %%1 IN ("%~f0") DO ( %\n%
if "%%1" == ":: Begin !par.listname! {" ( %\n%
set /a inside_list+=1 %\n%
) %\n%
if "%%1" == ":: End !par.listname! }" ( %\n%
set /a inside_list+=1 %\n%
) %\n%
if !inside_list! == 1 ( %\n%
if "!par.host!" == "%%1" ( %\n%
set "found_result=%%1,%%2" %\n%
) %\n%
) %\n%
) %\n%
FOR /F %%V in (""!found_result!"") do ( %\n%
endlocal %\n%
set "result=%%~V" %\n%
) %\n%
)) else setlocal EnableDelayedExpansion ^& set args=
echo Test Macro
%@{selezionaPOS}% "%HOSTN%" "Host-Pos list"
echo Host record found: %result%
:ESCI
exit /b 1000
:: Begin Host-Pos list {
PRM014BBIBL04,BIBLIOTECA01,192.168.14.55,02220195
WIN030XELETT10,COMUNE01,192.168.30.101,02220168
PRM021ASPEU01,DIGIPASS01,192.168.21.142,02220917
; questa è una riga di commento e viene ignorata
:: End Host-Pos list }
输出:
Test Macro
par.host=WIN030XELETT10
par.listname=Host-Pos list
Host record found: WIN030XELETT10,COMUNE01,192.168.30.101,02220168
要拆分结果并分配它,请替换结果 block
FOR /F "tokens=1-4 delims=," %%1 in ("!found_result!,") do ( %\n%
endlocal %\n%
set "hostname=%%~1" %\n%
set "posName=%%~2" %\n%
set "posIP=%%~3" %\n%
set "posID=%%~4" %\n%
) %\n%
额外的,
仅适用于found_result
为空的情况
关于batch-file - 变量没有跨越我的脚本中的 endlocal 屏障,或者宏定义中的语法存在一些错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73960155/