批处理:不解析键值的注释



我使用以下代码来解析配置文件.ini文件:

@setlocal enableextensions enabledelayedexpansion
@echo off
set file=%~1
set area=[%~2]
set key=%~3
set currarea=
for /f "usebackq delims=" %%a in ("!file!") do (
set ln=%%a
if "x!ln:~0,1!"=="x[" (
set currarea=!ln!
) else (
for /f "tokens=1,2 delims==" %%b in ("!ln!") do (
set currkey=%%b
set currval=%%c
if "x!area!"=="x!currarea!" if "x!key!"=="x!currkey!" (
echo !currval!
)
)
)
)
endlocal

只要与键和值在同一行中没有注释,它就可以正常工作。

例如:

[BACKUP]
HOST=128.110.111.11   ;Comment is included in !currval!
PORT=5901
USER=user1

不幸的是,我找不到一种方法来排除字符串"128.110.111.11"最后一个字符之后的所有内容。

任何帮助,不胜感激。谢谢!

实现目标的最佳批处理是用于处理字符串的 for 循环的组合。没有先天的命令可以在一个步骤中实现这一目标。

但在某种程度上,您可以通过将它们作为宏分配给变量来制作一个命令来完成必要的命令集

。例如,在下面的脚本中,宏通过以下方式完成此目标的必要步骤:

  • 使用;分隔变量内容
  • 从头到尾循环访问字符串的长度 - 该示例假定最大字符串长度为 250 个字符;示例点的任意数字。
  • 仅使用 If 条件逻辑和子字符串修改删除尾随空格
  • 通过使用 true/false 开关来停止对变量内容的进一步修改,以标记字符串的最后一位包含非空格字符

注意:子字符串修改用于宏扩展点,以提供要处理的变量的名称。

@Echo off & Setlocal enableDelayedexpansion
Set "RemTrail=Set "end=0"&(For /F "Tokens=1 Delims=;" %%G in ("^^!$v^^!")Do Set "$V=%%G")&For /L %%i in (250,-1,0)Do (if "^^!$V:~%%i,1^^!"==" " (If not "^^!End^^!"=="1" Set "$V=^^!$V:~0,%%i^^!")Else (If not "^^!$V:~%%i,1^^!"=="" Set "End=1"))"
rem // usage  example
Set "string=trail of spaces    ; comment string  "
Set "string2=uncommented string with trailing spaces and poison chars < &  " " | * >  "
Echo/[!string!]
Echo/[!string2!]
%RemTrail:$V=String%
%RemTrail:$V=String2%
Echo/[!string!]
Echo/[!string2!]

一个稍微修改的版本,允许在扩展时修改分隔符,代价是返回固定返回变量 ($V) 而不是原始变量名的修改结果:

@Echo off & Setlocal enableDelayedexpansion
Set "RemTrail=For %%n in (1 2)Do if %%n==2 (Set "end=0"&(For /F "Tokens=1 Delims=DLM" %%G in ("^^!$V^^!")Do Set "$V=%%~G")&For /L %%i in (250,-1,0)Do (if "^^!$V:~%%i,1^^!"==" " (If not "^^!End^^!"=="1" Set "$V=^^!$V:~0,%%i^^!")Else (If not "^^!$V:~%%i,1^^!"=="" Set "End=1")))Else Set $V="
rem // usage  example
Set "string=trail of spaces    ; comment string  "
Set "string2=uncommented string with trailing spaces + poison chars < & | * " " >  "
Echo/[!string!]
Echo/[!string2!]
%RemTrail:DLM=;%"!string!"
Echo/[!$V!]
%RemTrail:DLM=;%"!string2!"
Echo/[!$V!]
%RemTrail:DLM=+%"!string2!"
Echo/+ Delim example&Echo/[!$V!]

解决方案 1:

for /f "usebackq delims=;" %%a in ("!file!") do (

包括分号作为分隔符可确保仅将分号部分分配给token 1而默认情况下分配给元变量%%a

缺点:字符串末尾和分号之间的空格保留在%%a中,因此currval,并且将被echo编辑。

解决方案 2 :

for /f "tokens=1,2 delims== " %%b in ("!ln!") do (

将空格作为额外的分隔符包含在内,会将找到的第一个分隔符(=)和第二个分隔符([空格])之间的值分配给%%c

缺点:显示为%%c的值将在空格处被截断

解决方案 3:

使用解决方案 1,然后更改

set currval=%%c

CALL :setcurrval %%c

然后endlocal变成

endlocal
goto :eof
:setcurrval
SET "currval=%*"
goto :eof

终止本地环境并退出批处理。
CALL内部子例程:setcurrval将行的其余部分的值分配给currval,除了终端空间,因此产生%%c减去任何终端空间。

请注意,冒号很重要。

最新更新