[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

[文本处理] [已解决]批处理怎样修改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了):
  1. @echo off&setlocal enabledelayedexpansion
  2. (for /f "tokens=1* delims=:" %%a in ('findstr /n .* HIVEDEF.INF') do if "%%b"=="" (echo/) else (
  3.         set/a a+=1
  4.         if !a!==1 echo %%b
  5.         if !a!==5 for /f "tokens=1-3* delims=," %%c in ("%%b") do echo %%c,%%d,"2",%%f
  6. ))>temp.h
  7. del /q HIVEDEF.INF
  8. ren temp.h HIVEDEF.INF
复制代码
我测试了一下,产生的是一个空文本。另外,猜了一通代码,大概因为我上次没说清楚,感觉此方案似乎仅考虑了所要处理的几行,没考虑8000多行的批处理环境————不知我说的对不对?

附件:HIVEDEF.INF原件。原件305KB,我只有上传小于51.2KB附件的权限,压缩成RAR格式又不允许上传,就在RAR后面又加了个.inf扩展名,下载后删除.inf扩展名就能解压缩了。
附件: 您需要登录才可以下载或查看附件。没有帐号?注册
1

评分人数

    • Batcher: 感谢给帖子标题标注[已解决]字样PB + 2

1,楼主下回一定要把问题说清楚,不要怕麻烦。
2,任何压缩文件,不论扩展名是什么,直接拖到压缩程序上,都可以打开,不需要改扩展名。
3,输出为空白是因为 findstr 和 for 只能正常处理 ASCII 编码,不能处理 Unicode 编码,而楼主并没有说明此文件编码类型。
输出为 ASCII 编码,文件都可以使用绝对路径,保留空行,保留行首字符为;的行:
  1. @echo off&setlocal enabledelayedexpansion
  2. type "HIVEDEF.inf">"Han.temp"
  3. (for /f "eol=寒 tokens=1* delims=:" %%a in ('findstr /n .* "Han.temp"') do if "%%b"=="" (echo/) else (
  4.         set "Ye=%%b"
  5.         if /i "!Ye:~6,23!"=="Keyboard Layout\Preload" (
  6.                 if "!Ye:~32,1!"=="5" echo !Ye:~0,32!2!Ye:~33!
  7.                 if "!Ye:~32,1!"=="1" echo !Ye!
  8.                 ) else (
  9.                 echo !Ye!
  10.                 )
  11.         )
  12. )>"HIVEDEF.inf"
  13. del /q "Han.temp"
复制代码

怎么我一发这个字符,后面的东西就全没了,郁闷。。。
放附件里了:

[ 本帖最后由 hanyeguxing 于 2010-12-14 20:22 编辑 ]
附件: 您需要登录才可以下载或查看附件。没有帐号?注册
1

评分人数

寒夜孤星:在没有说明的情况下,本人所有代码均运行在 XP SP3 下 (有问题请发贴,QQ临时会话已关闭)

TOP

太感谢你了,我的朋友!

说实话,我也想把处理文本学会,但学了很久,进展不大。也是没太用功吧。
寒夜孤星朋友给我两三次代码了,我得好好拆解一番,争取有点进步。
你的代码中最让我看不懂的就是诸如“!Ye:~6,23!“这样的内容。一看就头大起来。记得在DOS联盟论坛见过一个专门示范这个参数用法的批处理,我再找找它,练一练。不懂再来问你。

TOP

回复 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
1

评分人数

我帮忙写的代码不需要付钱。如果一定要给,请在微信群或QQ群发给大家吧。
【微信公众号、微信群、QQ群】http://bbs.bathome.net/thread-3473-1-1.html
【支持批处理之家,加入VIP会员!】http://bbs.bathome.net/thread-67716-1-1.html

TOP

A.先要谢谢管理员Batcher雪中送炭!————呵呵,你给的链接无法收藏,只好从搜索里找标题,一个一个找到收藏起来。

B.说说我的阶段性学习成果:代码粗通一二,逻辑大惑不解

认真研读寒夜孤星的代码,终于读懂了一些基本的东西。内心感谢寒夜孤星所费的心思,感谢你的劳动和帮助!

对这一段代码有读懂的,也有疑惑:
  1. if /i "!Ye:~6,23!"=="Keyboard Layout\Preload" (
  2.                 if "!Ye:~32,1!"=="5" echo !Ye:~0,32!2!Ye:~33!
  3.                 if "!Ye:~32,1!"=="1" echo !Ye!
  4.                 ) else (
  5.                 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 编辑 ]

TOP

另外,第一次发帖时没讲清楚UNCODE码的文本属性,这可是个大问题。处理文本水平太差,丢三拉四没想到,也没注意到。 以后发这样的求助帖最好附上原件。这次是寒夜孤星朋友自己发现的,一定让他折腾了半天不见效果才找到这个原因的,抱歉!

TOP

1,if ......(命令1) else 命令2 如果满足条件则执行命令1,否则执行命令2
2,批处理解析文本时,有无英文敏感字符和编码类型是关键
  1. if /i "!Ye:~6,23!"=="Keyboard Layout\Preload" (
  2.                 if "!Ye:~32,1!"=="5" echo !Ye:~0,32!2!Ye:~33!
  3.                 if "!Ye:~32,1!"=="1" echo !Ye!
  4.                 ) else (
  5.                 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! 替换输出
1

评分人数

寒夜孤星:在没有说明的情况下,本人所有代码均运行在 XP SP3 下 (有问题请发贴,QQ临时会话已关闭)

TOP

看了半天,终于想明白了:
原来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 编辑 ]

TOP

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 编辑 ]

TOP

这可真是个检讨贴,从头检讨到尾。呵呵!够经典。

不过,收获太大了:得到代码,学到东西,交到朋友。。。。。。怎么检讨都值了。嘿嘿!

TOP

返回列表