在INI文件替换值 - 罗霍的剧本 [英] Replace value in INI file - Rojo's script
问题描述
我发现位于罗霍的很酷的批处理脚本在这里:阅读从Windows批处理文件的ini ,它的伟大工程,但有1怪癖,我想不通。任何时候遇到一个和放大器;在批处理文件,它会尝试执行什么紧跟。
下面是一个例子ini文件:
密码= 3]#{$ [1 [HX&安培; _r?URL = HTTP://www.osha.gov/pls/oshaweb/owasrch.search_form p_doc_type =标准和安培; p_toc_level = 0
在执行
C:\\脚本\\批> INI /我的数据库/ V MP2C:\\ ProgramData \\ Infor公司\\ MP2 6.1 SQL服务器版\\ Mp2_2.ini
MP2
_r不被识别为一个内部或外部命令,可操作的程序或批处理文件。
p_toc_level不被识别为一个内部或外部命令,可操作的程序或批处理文件。
在这里你去马特。我没有那样彻底,因为它应该是,所以请让我知道,如果你有任何问题,它测试了。我花了一点时间打磨它,觉得它已经彻底的测试后,我可能会更新我的上阅读从Windows批处理文件页为好。
@if(@a == @二)@end / * - 批/ JScript的混合线路开始JScript的评论:: --------------------
:: ini.bat
:: ini.bat /?对于使用
:: --------------------关闭@echo
SETLOCAL enabledelayedexpansion转到开始:: $彩c。通过杰布$ C - http://stackoverflow.com/a/5344911/1683264
:C
设置参数= ^%〜2!
设置参数=参数:!!= \\
FINDSTR / P / A:%1。 !参数!\\ .. \\ XNUL
< NUL集/ P。=%DEL %% DEL %% DEL %% DEL %% DEL %% DEL %% DEL%。
退出/ B
::但是它不处理斜线。 :(
:■
< NUL集/ P= /&放大器;出口/ B:用法
FOR / F令牌= 1,2 = delims#%%一个在('提示#$ H#$ E#&安培; echo开&安培;在(1)做REM %% B)并设置DEL = %%一个
<&NUL GT; ×给定/ P=。回声用法:
呼吁:C 07查询:
呼吁:C 0F%〜NX0&放大器;致电:S&放大器;呼吁:C 0F我的项目[&放大器;致电:S&放大器;呼吁:C 0FS段] INIFILE&放大器;回声;
呼吁:C 07创建或修改:
呼吁:C 0F%〜NX0&放大器;致电:S&放大器;呼吁:C 0F我的项目&放大器;致电:S&放大器;呼吁:C 0FV值[&放大器;致电:S&放大器;呼吁:C 0FS段] INIFILE&放大器;回声;
呼吁:C 07删除:
呼吁:C 0F%〜NX0&放大器;致电:S&放大器;呼吁:C 0FD项[&放大器;致电:S&放大器;呼吁:C 0FS段] INIFILE&放大器;回声;
回声;
回声就拿下面的ini文件:
回声;
回声[配置]
回声密码= 1234
呼应usertries = 0
呼应allowterminate = 0
回声;
呼应阅读密码的价值:
呼吁:C 0F%〜NX0&放大器;致电:S&放大器;呼吁:C 0FS配置&放大器;致电:S&放大器;呼吁:C 0F我的密码INIFILE&放大器;回声;
回声;
呼应要修改usertries的值改为5:
呼吁:C 0F%〜NX0&放大器;致电:S&放大器;呼吁:C 0FS配置&放大器;致电:S&放大器;呼吁:C 0F我usertries&放大器;致电:S&放大器;呼吁:C 0FV 5 INIFILE&放大器;回声;
回声;
为了呼应与当前日期和时间值增加一个时间戳键:
呼吁:C 0F%〜NX0&放大器;致电:S&放大器;呼吁:C 0FS配置&放大器;致电:S&放大器;呼吁:C 0F我时间戳&放大器;致电:S&放大器;呼吁:C 0FV DEL%日期%%%%% %%%% %%%%时间%%%%%DEL%INIFILE&放大器;回声;
回声;
呼应删除allowterminate键:
呼吁:C 0F%〜NX0&放大器;致电:S&放大器;呼吁:C 0FS配置&放大器;致电:S&放大器;呼吁:C 0FD allowterminate INIFILE&放大器;回声;
回声;
呼吁:C 07在上面的例子,&放大器;拨打:■
呼吁:C 0FS配置
回声是可选的,但将允许的选择
其中,呼应ini文件中包含多个部分类似项目的具体项目。
德尔点¯x
GOTO:EOF:开始
如果%〜1==goto语句用法
为%%我(项值部分中找到)并设置%% I =
为%%我在(%*)做(
如果下一个定义(
如果!下!== /我设置项= %%〜我
如果!下!== / V(
设置修改=真
设置值= %%〜我
)
如果!下!== / D(
设置项= %%〜我
设置修改=真
设置删除= TRUE
)
如果!下!== / s的设置一节= %%〜我
接着设置=
)其他(
在%% X(/ I / V / S / D)做,如果%%〜我==%% X设置下一步= %%〜我
如果没有下一个定义(
设置ARG = %%〜我
如果ARG:〜!0,1!==/(
1>和2回声错误:无法识别的选项%%〜我
1>和2回声;
1>和2呼叫:使用
退出/ B 1
),否则设置INIFILE = %%〜我
)
)
)
为%%我在(项目INIFILE)不要。如果没有定义%%我转到使用
如果不存在%INIFILE%(
1>和2回声错误:%INIFILE%没有找到。
退出/ B 1
)CSCRIPT / NOLOGO / E:JScript的%〜F0%INIFILE%,节! !项目! !值! 修改%%%删除%退出/ B%ERRORLEVEL%::开始JScript的部分* /
变种INIFILE = WSH.Arguments(0),
节= WSH.Arguments(1),
项= WSH.Arguments(2),
值= WSH.Arguments(3),
修改= WSH.Arguments(4),
德尔= WSH.Arguments(5),
FSO =新的ActiveXObject(Scripting.FileSystemObject的),
流= fso.OpenTextFile(INIFILE,1),//(stream.ReadAll()不会preserve空行。)
数据= [];
而(stream.atEndOfStream!){data.push(stream.ReadLine()); }
stream.Close();//修剪从空白开始和结束,返回小写
String.prototype.unify =函数(){返回this.replace(/ ^ \\ S + | \\ s + $ /,'')与toLowerCase(); };//刚刚过去的非空元素拼接后,一个新的元素到一个数组。如果第一个参数是一个数字,开始在该位置和向后看。
Array.prototype.cram =功能(){
对于(变参= [],I = 0; I<与arguments.length;我++){args.push(参数[I]); }
VAR I =(typeof运算ARGS [0] ==号与&&安培; Math.floor(参数[0])== ARGS [0])? args.shift():this.length;
而(ⅰ大于0&放大器;&放大器;该[ - I]。长度!){};
对于(VAR J = 0; J< args.length; J ++)this.splice(++我,0,ARGS [J]);
}功能saveAndQuit(){
而(数据&安培;&安培;!数据[data.length - 1]。长度)data.pop();
VAR流= fso.OpenTextFile(INIFILE,2,TRUE);
stream.Write(data.join('\\ r \\ n')+'\\ r \\ n);
stream.Close();
WSH.Quit(0);
}功能致命(ERR){
WSH.StdErr.WriteLine(ERR);
WSH.Quit(1);
}如果(节&安培;&安培;![+ \\]。/ ^ \\ $ /测试(部分))部分='['+部分+']';如果(修改){
如果(部分){
对于(VAR I = 0; I< data.length;我++){
如果(数据[I] .unify()== section.unify()){
对于(VAR J = I + 1; J< data.length; J ++){
如果(/^\\s*\\[.+\\]\\s*$/.test(data[j))打破;
VAR KEYVAL =数据[J] .split('=')|| [];
如果(keyval.length 2)继续;
VAR键= keyval.shift(),VAL = keyval.join('=');
如果(key.unify()== item.unify()){
如果(德尔)data.splice(J,1);
其他{
数据[J] =项目+=+值;
WSH.Echo(值);
}
saveAndQuit();
}
}
;如果(DEL)致命的(项目+ + +节在'+ INIFILE中找不到)
data.cram(J,项目+=+值);
WSH.Echo(值);
saveAndQuit();
}
}
如果(DEL)致命的(部分+'中找不到'+ INIFILE);
data.cram('\\ r \\ n'+部分,项目+=+值);
WSH.Echo(值);
saveAndQuit();
}
其他{//如果(!部分)
对于(VAR I = 0; I< data.length;我++){
VAR KEYVAL =数据[I] .split('=')|| [];
如果(keyval.length 2)继续;
VAR键= keyval.shift(),VAL = keyval.join('=');
如果(key.unify()== item.unify()){
如果(德尔)data.splice(I,1);
其他{
数据[I] =项目+=+值;
WSH.Echo(值);
}
saveAndQuit();
}
}
如果(DEL)致命的(项目+ + INIFILE'中找不到');
data.cram(项目+=+值);
WSH.Echo(值);
saveAndQuit();
}
}
否则,如果(部分){//如果(!修改)
对于(VAR I = 0; I< data.length;我++){
如果(数据[I] .unify()== section.unify()){
对于(VAR J = I + 1; J< data.length; J ++){
如果(/^\\s*\\[.+\\]\\s*$/.test(data[j))致命的(项目+ + +节在''没有发现'+ INIFILE);
VAR KEYVAL =数据[J] .split('=')|| [];
如果(keyval.length 2)继续;
VAR键= keyval.shift(),VAL = keyval.join('=');
如果(key.unify()== item.unify()){
WSH.Echo(VAL);
WSH.Quit(0);
}
}
}
}
致命的(部分+'中找不到'+ INIFILE);
}
其他{//如果(项目),并没有别的
对于(VAR I = 0; I< data.length;我++){
VAR KEYVAL =数据[I] .split('=')|| [];
如果(keyval.length 2)继续;
VAR键= keyval.shift(),VAL = keyval.join('=');
如果(key.unify()== item.unify()){
WSH.Echo(VAL);
WSH.Quit(0);
}
}
致命的(项目+'中找不到'+ INIFILE);
}
更新
该脚本的应的preserve并返回相应的%ERRORLEVEL%
。成功返回 0
的值;错误, 1
。
另外,我做了一些使用的的code 使用文件prettier。
I found Rojo's really cool batch script located here: Read ini from windows batch file and it works great but there is 1 quirk that I can't figure out. Any time it encounters an & in the batch file, it tries to execute what immediately follows.
Here's an example ini file:
Password=3]#{$[1[Hx&_r
URL=http://www.osha.gov/pls/oshaweb/owasrch.search_form?p_doc_type=STANDARDS&p_toc_level=0
upon execution
C:\Scripts\Batch>INI /i Database /v MP2 "C:\ProgramData\Infor\MP2 6.1 SQL Server Edition\Mp2_2.ini"
MP2
'_r' is not recognized as an internal or external command,operable program or batch file.
'p_toc_level' is not recognized as an internal or external command,operable program or batch file.
Here you go Matt. I haven't tested this as thoroughly as it ought to be, so please let me know if you have any problems with it. After I spend a little time polishing it and feel that it's been thoroughly tested, I might update my answer on that Read ini from Windows batch file page as well.
@if (@a==@b) @end /* -- batch / JScript hybrid line to begin JScript comment
:: --------------------
:: ini.bat
:: ini.bat /? for usage
:: --------------------
@echo off
setlocal enabledelayedexpansion
goto begin
:: color code by jeb -- http://stackoverflow.com/a/5344911/1683264
:c
set "param=^%~2" !
set "param=!param:"=\"!"
findstr /p /A:%1 "." "!param!\..\X" nul
<nul set /p ".=%DEL%%DEL%%DEL%%DEL%%DEL%%DEL%%DEL%"
exit /b
:: but it doesn't handle slashes. :(
:s
<NUL set /p "=/"&exit /b
:usage
for /F "tokens=1,2 delims=#" %%a in ('"prompt #$H#$E# & echo on & for %%b in (1) do rem"') do set "DEL=%%a"
<nul > X set /p ".=."
echo Usage:
call :c 07 " query:"
call :c 0F " %~nx0 "&call :s&call :c 0F "i item ["&call :s&call :c 0F "s section] inifile"&echo;
call :c 07 " create or modify:"
call :c 0F " %~nx0 "&call :s&call :c 0F "i item "&call :s&call :c 0F "v value ["&call :s&call :c 0F "s section] inifile"&echo;
call :c 07 " delete:"
call :c 0F " %~nx0 "&call :s&call :c 0F "d item ["&call :s&call :c 0F "s section] inifile"&echo;
echo;
echo Take the following ini file for example:
echo;
echo [Config]
echo password=1234
echo usertries=0
echo allowterminate=0
echo;
echo To read the "password" value:
call :c 0F " %~nx0 "&call :s&call :c 0F "s Config "&call :s&call :c 0F "i password inifile"&echo;
echo;
echo To modify the "usertries" value to 5:
call :c 0F " %~nx0 "&call :s&call :c 0F "s Config "&call :s&call :c 0F "i usertries "&call :s&call :c 0F "v 5 inifile"&echo;
echo;
echo To add a "timestamp" key with a value of the current date and time:
call :c 0F " %~nx0 "&call :s&call :c 0F "s Config "&call :s&call :c 0F "i timestamp "&call :s&call :c 0F "v ""%DEL%%%%%date%%%% %%%%time%%%%""%DEL% inifile"&echo;
echo;
echo To delete the "allowterminate" key:
call :c 0F " %~nx0 "&call :s&call :c 0F "s Config "&call :s&call :c 0F "d allowterminate inifile"&echo;
echo;
call :c 07 "In the above examples, "&call :s
call :c 0F "s Config "
echo is optional, but will allow the selection of
echo a specific item where the ini file contains similar items in multiple sections.
del X
goto :EOF
:begin
if "%~1"=="" goto usage
for %%I in (item value section found) do set %%I=
for %%I in (%*) do (
if defined next (
if !next!==/i set "item=%%~I"
if !next!==/v (
set modify=true
set "value=%%~I"
)
if !next!==/d (
set "item=%%~I"
set modify=true
set delete=true
)
if !next!==/s set "section=%%~I"
set next=
) else (
for %%x in (/i /v /s /d) do if "%%~I"=="%%x" set "next=%%~I"
if not defined next (
set "arg=%%~I"
if "!arg:~0,1!"=="/" (
1>&2 echo Error: Unrecognized option "%%~I"
1>&2 echo;
1>&2 call :usage
exit /b 1
) else set "inifile=%%~I"
)
)
)
for %%I in (item inifile) do if not defined %%I goto usage
if not exist "%inifile%" (
1>&2 echo Error: %inifile% not found.
exit /b 1
)
cscript /nologo /e:jscript "%~f0" "%inifile%" "!section!" "!item!" "!value!" "%modify%" "%delete%"
exit /b %ERRORLEVEL%
:: Begin JScript portion */
var inifile = WSH.Arguments(0),
section = WSH.Arguments(1),
item = WSH.Arguments(2),
value = WSH.Arguments(3),
modify = WSH.Arguments(4),
del = WSH.Arguments(5),
fso = new ActiveXObject("Scripting.FileSystemObject"),
stream = fso.OpenTextFile(inifile, 1),
// (stream.ReadAll() will not preserve blank lines.)
data = [];
while (!stream.atEndOfStream) { data.push(stream.ReadLine()); }
stream.Close();
// trims whitespace from beginning and end, returns lower case
String.prototype.unify = function() { return this.replace(/^\s+|\s+$/,'').toLowerCase(); };
// splices a new element into an array just after the last non-empty element. If first arg is a number, start at that position and look backwards.
Array.prototype.cram = function() {
for (var args=[], i=0; i<arguments.length; i++) { args.push(arguments[i]); }
var i = (typeof args[0] == "number" && Math.floor(args[0]) == args[0]) ? args.shift() : this.length;
while (i>0 && !this[--i].length) {};
for (var j=0; j<args.length; j++) this.splice(++i, 0, args[j]);
}
function saveAndQuit() {
while (data && !data[data.length - 1].length) data.pop();
var stream = fso.OpenTextFile(inifile, 2, true);
stream.Write(data.join('\r\n') + '\r\n');
stream.Close();
WSH.Quit(0);
}
function fatal(err) {
WSH.StdErr.WriteLine(err);
WSH.Quit(1);
}
if (section && !/^\[.+\]$/.test(section)) section = '[' + section + ']';
if (modify) {
if (section) {
for (var i=0; i<data.length; i++) {
if (data[i].unify() == section.unify()) {
for (var j=i + 1; j<data.length; j++) {
if (/^\s*\[.+\]\s*$/.test(data[j])) break;
var keyval = data[j].split('=') || [];
if (keyval.length < 2) continue;
var key = keyval.shift(), val = keyval.join('=');
if (key.unify() == item.unify()) {
if (del) data.splice(j, 1);
else {
data[j] = item + '=' + value;
WSH.Echo(value);
}
saveAndQuit();
}
}
if (del) fatal(item + ' not found in ' + section + ' in ' + inifile);
data.cram(j ,item + '=' + value);
WSH.Echo(value);
saveAndQuit();
}
}
if (del) fatal(section + ' not found in ' + inifile);
data.cram('\r\n' + section, item + '=' + value);
WSH.Echo(value);
saveAndQuit();
}
else { // if (!section)
for (var i=0; i<data.length; i++) {
var keyval = data[i].split('=') || [];
if (keyval.length < 2) continue;
var key = keyval.shift(), val = keyval.join('=');
if (key.unify() == item.unify()) {
if (del) data.splice(i, 1);
else {
data[i] = item + '=' + value;
WSH.Echo(value);
}
saveAndQuit();
}
}
if (del) fatal(item + ' not found in ' + inifile);
data.cram(item + '=' + value);
WSH.Echo(value);
saveAndQuit();
}
}
else if (section) { // and if (!modify)
for (var i=0; i<data.length; i++) {
if (data[i].unify() == section.unify()) {
for (var j=i + 1; j<data.length; j++) {
if (/^\s*\[.+\]\s*$/.test(data[j])) fatal(item + ' not found in ' + section + ' in ' + inifile);
var keyval = data[j].split('=') || [];
if (keyval.length < 2) continue;
var key = keyval.shift(), val = keyval.join('=');
if (key.unify() == item.unify()) {
WSH.Echo(val);
WSH.Quit(0);
}
}
}
}
fatal(section + ' not found in ' + inifile);
}
else { // if (item) and nothing else
for (var i=0; i<data.length; i++) {
var keyval = data[i].split('=') || [];
if (keyval.length < 2) continue;
var key = keyval.shift(), val = keyval.join('=');
if (key.unify() == item.unify()) {
WSH.Echo(val);
WSH.Quit(0);
}
}
fatal(item + ' not found in ' + inifile);
}
Update
The script should preserve and return the appropriate %ERRORLEVEL%
. Success returns a value of 0
; error, 1
.
Also, I made the usage documentation prettier using some of jeb's code.
这篇关于在INI文件替换值 - 罗霍的剧本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!