标题: [文本处理] [已解决]批处理怎样修改HIVEDEF.INF文本及环境限制? [打印本页]
作者: stance 时间: 2010-12-14 13:24 标题: [已解决]批处理怎样修改HIVEDEF.INF文本及环境限制?
先检讨:
前天发了个求助帖http://www.bathome.net/thread-10307-1-1.html,因为标题不符合论坛规则,被锁了。在此向论坛道歉,新来的不懂规矩,请原谅。本人支持论坛的管理规则。
那个帖子发的仓促,的确有问题:一是标题不明确(已经改了一下),二是内容有错误,把HIVEDEF.INF写成了HIVESYS.INF(也改了),三是对处理文本的环境没描述清楚。锁了也不冤。只是对帮助解决问题的寒夜孤星朋友更表歉意。
再提问题:
修改HIVEDEF.INF文本的实际情况有点复杂:
1、HIVEDEF.INF的文本很长,共有8000多行。它里面有3个[addreg]段,要修改的内容属于第3个[addreg]段的第二部分。如果连空行也算行的话,这部分内容在第3个[addreg]段下数从第12行开始,至第15行截止。内容为:
HKCU,"Keyboard Layout\Preload","2",0x00000002,"E00E0804"
HKCU,"Keyboard Layout\Preload","3",0x00000002,"E0010804"
HKCU,"Keyboard Layout\Preload","4",0x00000002,"E0030804"
HKCU,"Keyboard Layout\Preload","5",0x00000002,"E0040804"
2、批处理的工作目标:删除前三行,把第五行的"5"改成"2"。
3、要删除和修改行中有"2",、"3",、"4",、"5",这样的特征值——必须给数字加上前后引号"",后面再跟一个,号,才可以作为该行的特征值,在整个文本中具有唯一性,否则其他行中有的也有只加""号不跟,号的"2"、"3"、"4"、"5"。
修改文本的初步设想(不知道思路对不对,是不是有更好的办法):
1、全文检索,查找"2",、"3",、"4",、"5",特征值。
2、如果某行没有特征值,就输出到新文本中;
3、见到"2",、"3",、"4",就删除它所在的行(删除后不给它留下空行);
4、见到"5",就把它改成"2",。然后输出到新文本中。
修改文本的水平太菜,自己实在做不出来,再求朋友们帮忙。
寒夜孤星朋友给了一个批处理解决方案(这里把HIVESYS.INF改成HIVEINF.INF了):- @echo off&setlocal enabledelayedexpansion
- (for /f "tokens=1* delims=:" %%a in ('findstr /n .* HIVEDEF.INF') do if "%%b"=="" (echo/) else (
- set/a a+=1
- if !a!==1 echo %%b
- if !a!==5 for /f "tokens=1-3* delims=," %%c in ("%%b") do echo %%c,%%d,"2",%%f
- ))>temp.h
- del /q HIVEDEF.INF
- ren temp.h HIVEDEF.INF
复制代码
我测试了一下,产生的是一个空文本。另外,猜了一通代码,大概因为我上次没说清楚,感觉此方案似乎仅考虑了所要处理的几行,没考虑8000多行的批处理环境————不知我说的对不对?
附件:HIVEDEF.INF原件。原件305KB,我只有上传小于51.2KB附件的权限,压缩成RAR格式又不允许上传,就在RAR后面又加了个.inf扩展名,下载后删除.inf扩展名就能解压缩了。
作者: hanyeguxing 时间: 2010-12-14 17:48
1,楼主下回一定要把问题说清楚,不要怕麻烦。
2,任何压缩文件,不论扩展名是什么,直接拖到压缩程序上,都可以打开,不需要改扩展名。
3,输出为空白是因为 findstr 和 for 只能正常处理 ASCII 编码,不能处理 Unicode 编码,而楼主并没有说明此文件编码类型。
输出为 ASCII 编码,文件都可以使用绝对路径,保留空行,保留行首字符为;的行:- @echo off&setlocal enabledelayedexpansion
- type "HIVEDEF.inf">"Han.temp"
- (for /f "eol=寒 tokens=1* delims=:" %%a in ('findstr /n .* "Han.temp"') do if "%%b"=="" (echo/) else (
- set "Ye=%%b"
- if /i "!Ye:~6,23!"=="Keyboard Layout\Preload" (
- if "!Ye:~32,1!"=="5" echo !Ye:~0,32!2!Ye:~33!
- if "!Ye:~32,1!"=="1" echo !Ye!
- ) else (
- echo !Ye!
- )
- )
- )>"HIVEDEF.inf"
- del /q "Han.temp"
复制代码
怎么我一发[attach]3254[/attach]这个字符,后面的东西就全没了,郁闷。。。
放附件里了:[attach]3255[/attach]
[ 本帖最后由 hanyeguxing 于 2010-12-14 20:22 编辑 ]
作者: stance 时间: 2010-12-15 09:52 标题: 太感谢你了,我的朋友!
说实话,我也想把处理文本学会,但学了很久,进展不大。也是没太用功吧。
寒夜孤星朋友给我两三次代码了,我得好好拆解一番,争取有点进步。
你的代码中最让我看不懂的就是诸如“!Ye:~6,23!“这样的内容。一看就头大起来。记得在DOS联盟论坛见过一个专门示范这个参数用法的批处理,我再找找它,练一练。不懂再来问你。
作者: Batcher 时间: 2010-12-15 13:12 标题: 回复 4楼 的帖子
批处理set命令截取字符详解
http://bbs.bathome.net/thread-996-1-1.html
批处理set命令变量字符截取点点通
http://bbs.bathome.net/thread-40-1-1.html
批处理新手set命令截取字符练习工具
http://bbs.bathome.net/thread-1149-1-1.html
作者: stance 时间: 2010-12-15 22:55
A.先要谢谢管理员Batcher雪中送炭!————呵呵,你给的链接无法收藏,只好从搜索里找标题,一个一个找到收藏起来。
B.说说我的阶段性学习成果:代码粗通一二,逻辑大惑不解
认真研读寒夜孤星的代码,终于读懂了一些基本的东西。内心感谢寒夜孤星所费的心思,感谢你的劳动和帮助!
对这一段代码有读懂的,也有疑惑:
- if /i "!Ye:~6,23!"=="Keyboard Layout\Preload" (
- if "!Ye:~32,1!"=="5" echo !Ye:~0,32!2!Ye:~33!
- if "!Ye:~32,1!"=="1" echo !Ye!
- ) else (
- echo !Ye!
复制代码
先说读懂的:
!Ye:~6,23!是指抛弃前6个字符不计,从第7个字符开始计数,一共数出23个字符。这23个字符是Keyboard Layout\Preload(中间含一个空格算作一个字符)。
如果某行符合这个条件,再作进一步的条件限制后输出:
如果它的第33个字符是5,就输出第32个和34个字符之间是字符是2的字符串(这是采取逐个字符读取和输出的方式完成替换)。
如果它的第33个字符是1,就照原样输出它。
再说没读懂的:
else (echo !Ye!)——这个没读懂。它对应if /i "!Ye:~6,23!"=="Keyboard Layout\Preload" 。按照逻辑说,如果不属于子if语句的进一步限定范围的,都照原样输出,那么2、3、4也应该被输出出来,因为它们也符合Keyboard Layout\Preload限定条件。可实际输出结果却是完全符合设想的,它们确实被过滤掉了——耳畔响起小沈阳的熟话:“这是为什么呢?”
因为还有很多文本处理的事要做,很想把它搞明白。
[ 本帖最后由 stance 于 2010-12-15 23:16 编辑 ]
作者: stance 时间: 2010-12-15 23:27
另外,第一次发帖时没讲清楚UNCODE码的文本属性,这可是个大问题。处理文本水平太差,丢三拉四没想到,也没注意到。 以后发这样的求助帖最好附上原件。这次是寒夜孤星朋友自己发现的,一定让他折腾了半天不见效果才找到这个原因的,抱歉!
作者: hanyeguxing 时间: 2010-12-15 23:44
1,if ......(命令1) else 命令2 如果满足条件则执行命令1,否则执行命令2
2,批处理解析文本时,有无英文敏感字符和编码类型是关键- if /i "!Ye:~6,23!"=="Keyboard Layout\Preload" (
- if "!Ye:~32,1!"=="5" echo !Ye:~0,32!2!Ye:~33!
- if "!Ye:~32,1!"=="1" echo !Ye!
- ) else (
- echo !Ye!
复制代码
查找第5个字符开始,连续23个字符,看是不是Keyboard Layout\Preload,如果是(符合条件)则执行里面的两个if子命令,如果不是,则执行else里的子命令,即直接输出。
符合条件时,就把那5行都定位到了。他们的第31个字符分别是1-5,两个if 只对1和5操作,所有只输出1和5两行。
if "!Ye:~32,1!"=="1" echo !Ye! 直接输出
if "!Ye:~32,1!"=="5" echo !Ye:~0,32!2!Ye:~33! 替换输出
作者: stance 时间: 2010-12-16 01:42
看了半天,终于想明白了:
原来else是指if not "Keyboard Layout\Preload"而不是if not 1 2 3 4 5!!!对1 2 3 4 5的输出在if子命令中已经分别做了动作,没提到的自然屏蔽了。
原来是我的思维陷入误区了。
寒夜孤星不但是技术高手,也是一位好老师!得到您的悉心指教很幸运。
[ 本帖最后由 stance 于 2010-12-16 01:45 编辑 ]
作者: stance 时间: 2010-12-16 01:51 标题: 5楼这段话应当加一句
原话:
先说读懂的:
!Ye:~6,23!是指抛弃前6个字符不计,从第7个字符开始计数,一共数出23个字符。这23个字符是Keyboard Layout\Preload(中间含一个空格算作一个字符)。
如果某行符合这个条件,再作进一步的条件限制后输出:
如果它的第33个字符是5,就输出第32个和34个字符之间是字符是2的字符串(这是采取逐个字符读取和输出的方式完成替换)。
如果它的第33个字符是1,就照原样输出它。
补充之后的话:
先说读懂的:
!Ye:~6,23!是指抛弃前6个字符不计,从第7个字符开始计数,一共数出23个字符。这23个字符是Keyboard Layout\Preload(中间含一个空格算作一个字符)。
如果某行符合Keyboard Layout\Preload这个条件,再作进一步的条件限制后输出:
如果它的第33个字符是5,就输出第32个和34个字符之间是字符是2的字符串(这是采取逐个字符读取和输出的方式完成替换)。
如果它的第33个字符是1,就照原样输出它。
如果某行不符合Keyboard Layout\Preload这个条件,原样输出。(——补充的,就是因为缺这句话,才产生后边的疑问。)
[ 本帖最后由 stance 于 2010-12-16 01:53 编辑 ]
作者: stance 时间: 2010-12-16 02:01
这可真是个检讨贴,从头检讨到尾。呵呵!够经典。
不过,收获太大了:得到代码,学到东西,交到朋友。。。。。。怎么检讨都值了。嘿嘿!
欢迎光临 批处理之家 (http://bathome.net./) |
Powered by Discuz! 7.2 |