1. 简介
批处理并没有直接读写ini文件的功能。所以只能通过读取文件内容分析比较来找到相应段名、键名对应位置,然后提取相应字符串来做为读。写则是找到键名对应的内容,然后进行替换,重新新的文件然后覆盖原文件。
2. 读取
2.1. 前期处理
要求输出的参数有配置文件路径、段名、键名。并且这3个字符串都需要进行Trim处理,即消除字符串前后可能存在的空格,提升代码的兼容性与可靠性。
代码中用了3个代码标签希,提供Trim功能,其中利用到递归达到去除所有的空格。
2.2. 代码
@echo off
call :Begin "%~1" "%~2" "%~3"
:TrimLeft
set "var=%~1"
if "%var:~0,1%"==" " call :TrimLeft "%var:~1%"
goto :eof
:TrimRight
set "var=%~1"
if "%var:~-1%"==" " call :TrimRight "%var:~0,-1%"
goto :eof
:Trim
call :TrimLeft "%%~1%"
call :TrimRight "%var%"
goto :eof
:Begin
set "filePath=%~1"
call :Trim "%filePath%"
set "filePath=%var%"
set "section=%~2"
call :Trim "%section%"
set "section=[%var%]"
set "Key=%~3"
call :Trim "%Key%"
set "Key=%var%"
rem find是获取包括指定字符串的行号[linenumber]
rem usebackq表示in中的路径可能包含空格,delims=[]提取find找到的行号
for /f "usebackq delims=[]" %%i in (`find /i "%section%" /n %filepath%`) do set sectionName=%%i
setlocal EnableDelayedExpansion
rem token表示分配的字符串取前2个,按%%i自加,delims==表示以=分隔,skip表示跳过指定行数
for /f "usebackq tokens=1,2 delims== skip=%sectionName%" %%i in (`type %filepath%`) do (
set "KeyDst=%%i"
call :Trim "!KeyDst!"
set "KeyDst=!var!"
set "Value=%%j"
call :Trim "!Value!"
set "Value=!var!"
rem 找到下一个section[时退出
set "a=%%i"
if "!a:~0,1!"=="[" goto :eof
if "!KeyDst!"=="%Key%" (
echo key:%%i
echo value:!Value!
goto :eof
)
)
)
goto :eof
3. 修改
3.1. 前期处理
依然是要处理参数的空格问题。另外就是先找段名,再找到键名,再直接替换原有的内容,并生成到临时文件中。操作完之后,将临时文件替换原文件,并删除临时文件。有一点遗憾的是分号自动消除了,无法注释。
3.2. 代码
@echo off >temp.ini
call :Begin "%~1" "%~2" "%~3" "%~4"
:TrimLeft
set "var=%~1"
if "%var:~0,1%"==" " call :TrimLeft "%var:~1%"
goto :eof
:TrimRight
set "var=%~1"
if "%var:~-1%"==" " call :TrimRight "%var:~0,-1%"
goto :eof
:Trim
call :TrimLeft "%%~1%"
call :TrimRight "%var%"
goto :eof
:Begin
set "filePath=%~1"
call :Trim "%filePath%"
set "filePath=%var%"
set "section=%~2"
call :Trim "%section%"
set "section=[%var%]"
set "Key=%~3"
call :Trim "%Key%"
set "Key=%var%"
set "Val=%~4"
call :Trim "%Val%"
set "Val=%var%"
@echo off >tmp.ini
setlocal EnableDelayedExpansion
set /a flag=0
rem token表示分配的字符串取前2个,按%%i自加,delims==表示以=分隔,skip表示跳过指定行数
for /f "usebackq tokens=1* delims== " %%i in (`type %filepath%`) do (
set "KeyDst=%%i"
call :Trim "!KeyDst!"
set "KeyDst=!var!"
if "!var:~0,1!"=="[" (
echo.>>tmp.ini
echo %%i>>tmp.ini
echo %%i|find "%section%">nul&&set /a flag=1) else (
if !flag!==1 (
if "!KeyDst!"=="%Key%" (
echo %key%=%Val%>>tmp.ini
set /a flag=0
) else (
if %%j=="" (
echo %%i>>tmp.ini
) else echo %%i=%%j>>tmp.ini
)
) else (
if defined %%j (
echo %%i>>tmp.ini
) else echo %%i=%%j>>tmp.ini
))
)
copy tmp.ini %filepath% /y >nul||(attrib -s -a -r -h %filepath%& copy tmp.ini %filepath% /y >nul)
del tmp.ini
echo finish
goto :eof