批处理之读写ini配置文件

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章