batch-file - 变量没有跨越我的脚本中的 endlocal 屏障,或者宏定义中的语法存在一些错误

标签 batch-file

我编写了以下宏,我希望该宏将表的原始数据返回到底部,引用执行脚本的电脑的主机名,但它不起作用。 宏定义中的语法似乎有一些错误。 事实上,@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/

相关文章:

python - Jenkins 不在控制台中打印 python 脚本的输出

batch-file - 如何使用批处理脚本获取呈现特定文件夹的批处理脚本位置(以编程方式)

python - 将参数从批处理文件发送到 Python 脚本

windows - 如何在 Batch For 循环中获取 C++ 错误

windows - 在 Windows 上使用带有 for/f 的管道命令(使用 reg 查询)

html - 使用批处理生成 html .. 转义引号

windows - 使用 BAT/PS 脚本自动安装

linux - 如何将 Linux shell 脚本转换为 Windows 批处理文件?

file - 按文件中的列批量排序

windows - 将 CertUtil -hashfile 的结果保存到变量并删除散列的空格