批处理怎么读取和修改INI配置文件?

如何用批处理读取INI文件指定项后的键值?

举例: 1.ini 内容为

[okm]
abc=678
zxc=456
qwe=789
cxz=147

[cbd]
abc=123
qwe=321
qaz=534

wsx=765
edc=258
我想读取[cbd]下abc,qwe,qaz,wsx,这四个的值,但abc,qwe又在 [okm]存在相同的.我该怎么准确的提取[cbd]里我想要的四个值?
提取后还要修改所提取的四个值.这个批处理该怎么写呢?

@echo off&setlocal ENABLEDELAYEDEXPANSION
call :解析 1.ini
call :提取 okm abc
call :修改 okm abc newvalue
call :输出 >new.ini
goto :eof


:解析 [参数#1=ini文件路径]
set "op="
for /f " usebackq tokens=1* delims==" %%a in ("%~1") do (
if "%%b"=="" (
set "op=%%a"
) else (
set "##!op!#%%a=%%b"
)
)
goto :eof


:提取 [参数#1=Option] [参数#2=Key]
echo,Option=%~1,Key=%~2,Value=!##[%~1]#%~2!
goto :eof


:修改 [参数#1=Option] [参数#2=Key] [参数#3=value,没有参数3则删除该配置项]
set "##[%~1]#%~2=%~3"
goto :eof


:输出 [>新ini文件路径]
set "op="
for /f "tokens=1-3 delims=#=" %%a in ('set ##') do (
if "%%a"=="!op!" (
echo,%%b=%%c
) else (
echo,%%a
set "op=%%a"
echo,%%b=%%c
)
)

追问

没怎么看明白,能说明下吗?

追答

只需要在  1 - 6 行之间 加入你想要的操作就可以了, 第一个 goto :eof 之后的内容你完全不用管。


1、比如你要读取 c:\abc efd\1.ini 配置文件(含空格加引号),就用

call :解析 "c:\abc efd\1.ini"

2、比如你要提取显示 okm 下的 abc 的值,就用

call :提取 okm abc

3、你要修改 okm 下 abc 的值 ,改为  999,就用,改多少个值就用多少次:

call :修改 okm abc 999

4,你要输出成新配置文件到d:\abc\newconfig.ini,就用

call :输出 >d:\abc\newconfig.ini

追问

不行啊,提取出来在那里? 而且call :输出>2.ini,输出以后,整个INI全乱了.我需要的是能把我要的几个值,提取到一个新的文本,我修改了文本里的内容,然后再写入1.ini配置文件里.能有其他的方式写吗?

追答

第一, INI 文件配置项跟顺序无关,不影响使用。


第二,我不清楚你要批处理的目的是什么,方便修改? 哪我建议你直接用快捷方式到桌面更好,直接打开修改,方便快捷。


批处理的作用在于 大量的节省人的操作...

我还以为你有很多ini 文件需要修改,用批处理来处理。


另外,直接在批处理 设置 好你要修改的项 即可,不需要提取到新文件里,如果你要这么做,那么用这个:

call :提取 okm abc >新文件.ini

追问

我确实是需要大量的修改INI文件,所以手动填写修改是很麻烦的事.每个INI文件在不同的目录,我是想把目录名写在一个文本里,然后批处理提取我所需要修改的INI文件里的值到一个文本,然后我再把我要修改的值在文本里修改.再对应目录写回该目录里的原INI文件里.

追答

你这个做法不合理。

你应该要先知道 那些 配置项 需要修改,修改为什么值,然后执行批处理一次 修改所有值不对的ini

追问

要修改成什么值我肯定是知道的,这个值每一个都不一样.那些要修改的我也肯定是知道,但是分开在不同的目录,我不可能一个一个进去修改.,我只是把需要修改的INI文件里的值全部提取到一个文本,然后我在文本里修改以后,再把这文本里的值写入提取出来位置.

追答

那就简单多了,仔细代码阅读 说明,就可以了,默认没有开启回写。

@echo off&setlocal ENABLEDELAYEDEXPANSION

::list.txt 包含所有ini 文件路径
call :提取 list.txt >all.txt
notepad all.txt
echo,请先保存更改,再按任意键继续&pause>nul

::要回写请去掉call前的:  注意,这会替换原文件内容,原文件会备份为一个 以时间 开头的新文件。
:call :回写
goto :eof


:提取 [文件列表.txt]
for /f "usebackq delims=" %%a in ("%~1") do (
echo,@%%~a@
type "%%~a"
)
goto :eof




:回写
set "pt="
set "fn="
for /f "tokens=1* delims=:" %%a in ('findstr /n .* all.txt') do (
set "cut=%%b"
if "!cut:~0,1!"=="@" (
for /f "delims=@" %%p in ("%%b") do (
set "pt=%%~p"
set "fn=%%~np"
)
ren "!pt!" "!time::=!.!fn!.ini"
) else (
echo,%%b>>!pt!
)
)

 

未测试,虽然代码检查过,但可能会有问题。

追问

太头晕了.我都不知道该怎么改? list.txt里是什么路径格式? 绝对路径? 还是怎么? 还有这些需要提取出来的值怎么提取出来? 那些值我也是需要的. 而且回写,我该怎么写?

追答

路径随便,绝对,相对都可以。
比如:

c:\abc\a.ini
d:\ert fwa\d.ini
ab.ini
123\321\f.ini

这是提取所有值,你直接在all.txt文本中搜索,更改。


:call :回写 改为
call :回写
就可以,冒号是当注释用,这一行不会运行。

为什么提取所有行,是因为你说每个ini文件都不同,那么你要怎么定义那个ini文件提取那些行?

我觉得你走入了思维误区,你都知道要更新那些配置项了,还要提取出来干嘛。
你自己写一个文本,里面写好要更新哪些配置项,然后用程序,自动查找对比所有ini文件,把配置项更新过去可以了。

温馨提示:答案为网友推荐,仅供参考
第1个回答  2013-10-15
编写一个合适的list很重要,例如
ini路径 项名 键名 新的值
D:\?\1.ini cbd abc 321
D:\?\1.ini cbd qwe 321
D:\?\1.ini cbd qaz 321
D:\?\1.ini okm cxz 321

根据list结构,批处理就方便编写,这样做的好处是批处理编写好后将是固定的,要修改值间接在list中进行本回答被网友采纳
相似回答