Board logo

标题: [文本处理] 【已解决】批处理怎样通过比对目录中的文件更新文本? [打印本页]

作者: pan528    时间: 2013-7-16 13:19     标题: 【已解决】批处理怎样通过比对目录中的文件更新文本?

本帖最后由 pan528 于 2013-7-20 11:06 编辑

有一a文本,如下:
  1. 一、中央立法
  2. 1_1_关于中华人民共和国国都、纪年、国歌、国旗的决议
  3. 1_10_全国人民代表大会常务委员会批准国务院关于华侨捐资兴办学校办法的决议
  4. 1_100_全国人民代表大会常务委员会关于海南省出席第七届全国人民代表大会代表团组成的决定
  5. 1_101_中华人民共和国进出口商品检验法
  6. 1_102_中华人民共和国传染病防治法
  7. 1_103_中华人民共和国行政诉讼法
  8. 1_102742_全国人民代表大会常务委员会关于中国银行业监督管理委员会履行原由中国人民银行履行的监督管理职责的决定
  9. 1_1029721234_中华人民共和国澳门特别行政区第一届**推选委员会委员守则
  10. 2_12167_国务院关于发布《中华人民共和国一九八七年国库券条例》的通知
  11. 二、行政法规
  12. 2_12180_国务院关于违反财政法规处罚的暂行规定
  13. 2_12226_国家土地开发建设基金回收管理试行办法
  14. 2_12310_中共中央办公厅、国务院办公厅关于在国内公务活动中严禁用**宴请和有关工作餐的规定
  15. 2_122765_全民所有制工业企业承包经营责任制暂行条例(修订)
  16. 2_1253070_中华人民共和国进出口关税条例
  17. 三、**解释
  18. 3_1923_最高人民法院关于房屋典当回赎中几个有关问题的批复
  19. 3_1924_最高人民法院关于典当房屋回赎期限计算问题的批复
  20. 3_1925_最高人民法院关于韩荷敏等人与宁桂兰等人房屋继承案的批复
  21. 3_1926_最高人民法院关于产权人双方在“**”期间互换房屋各自行使权利多年后能否翻悔的批复
  22. 3_192250_最高人民**关于印发《关于进一步加强检察机关办案安全防范工作的意见》的通知
  23. 四、部门规章
  24. 4_11563_提存公证规则
  25. 4_11571_**行政机关行政赔偿、刑事赔偿办法
  26. 4_11595_律师资格考核授予办法
  27. 4_11596_合伙律师事务所管理办法
  28. 4_115887_火炬计划标志使用管理办法
  29. 4_11590600_大型运动会审计工作暂行规定
复制代码
而四个目录中的文件已发生变化,如下:
  1. law01\
  2. 1_1_关于中华人民共和国国都、纪年、国歌、国旗的决议
  3. 1_10_全国人民代表大会常务委员会批准国务院关于华侨捐资兴办学校办法的决议
  4. 1_100_全国人民代表大会常务委员会关于海南省出席第七届全国人民代表大会代表团组成的决定
  5. 1_101_中华人民共和国进出口商品检验法
  6. 1_102_中华人民共和国传染病防治法(2012)
  7. 1_103_中华人民共和国行政诉讼法(1989)
  8. 1_102742_全国人民代表大会常务委员会关于中国银行业监督管理委员会履行原由中国人民银行履行的监督管理职责的决定
  9. 1_1029721234_中华人民共和国澳门特别行政区第一届**推选委员会委员守则
  10. 2_12167_国务院关于发布《中华人民共和国一九八七年国库券条例》的通知
  11. law02\
  12. 2_12180_国务院关于违反财政法规处罚的暂行规定(2010)
  13. 2_12226_国家土地开发建设基金回收管理试行办法(2012)
  14. 2_12310_中共中央办公厅、国务院办公厅关于在国内公务活动中严禁用**宴请和有关工作餐的规定
  15. 2_122765_全民所有制工业企业承包经营责任制暂行条例(修订)
  16. 2_1253070_中华人民共和国进出口关税条例(2002)
  17. law03\
  18. 3_1923_最高人民法院关于房屋典当回赎中几个有关问题的批复(1980)
  19. 3_1924_最高人民法院关于典当房屋回赎期限计算问题的批复(1982)
  20. 3_1925_最高人民法院关于韩荷敏等人与宁桂兰等人房屋继承案的批复【失效】
  21. 3_1926_最高人民法院关于产权人双方在“**”期间互换房屋各自行使权利多年后能否翻悔的批复【废止】
  22. 3_192250_最高人民**关于印发《关于进一步加强检察机关办案安全防范工作的意见》的通知
  23. law04\
  24. 4_11563_提存公证规则(2012)
  25. 4_11571_**行政机关行政赔偿、刑事赔偿办法【失效】
  26. 4_11595_律师资格考核授予办法(2013)
  27. 4_11596_合伙律师事务所管理办法(2010)
  28. 4_115887_火炬计划标志使用管理办法
  29. 4_11590600_大型运动会审计工作暂行规定
复制代码
怎样根据前两位序号来更新文本?请高手指点。
作者: xxpinqz    时间: 2013-7-16 13:36

试试看,通用性不强,只能说解题。
  1. @echo off
  2. (for /f "tokens=1,2* delims=_" %%a in (a.txt) do (
  3.     set strb=
  4.     set/p strb=
  5.     setlocal enabledelayedexpansion
  6.     for /f "tokens=1,2* delims=_" %%i in ("!strb!") do (
  7.         endlocal
  8.         if "%%a_%%b"=="%%i_%%j" (
  9.          echo,%%a_%%b_%%k
  10.         ) else (
  11.             echo,%%a
  12.         )
  13.     )
  14. ))<b.txt>更新.txt
复制代码

作者: pan528    时间: 2013-7-16 14:27

回复 2# xxpinqz

怨我没有讲清楚。
第二部分是四个目录下的文件发生了变化后的情况,不是一个文本。
而且四个目录内不止这些文件,还有其他文件。
但文件的左边的双位代码或文件的名称是相同的,即一半的信息是一致的。

这种情况,应该怎样改代码?
作者: terse    时间: 2013-7-16 16:03

回复 3# pan528
你是想把第二部分得到的结果 和第一部分对比 如结果第一部分不包含的就加进 或者前面序列一致而后面内容不同的 就修改第一部分 使之和第二部分一致 是这样吗
但还有一处不明 目录怎么处理的
还有 加进去 怎么加
作者: pan528    时间: 2013-7-16 21:58

回复  pan528
你是想把第二部分得到的结果 和第一部分对比 如结果第一部分不包含的就加进 或者前面序列一 ...
terse 发表于 2013-7-16 16:03


第一行的理解是符合我的意思的。
但第二部分是目录中与第一部分相对应的文件,不是文本,因此,按我的理解,是要用第一部分的文本与目录(第二部分)中的文本比对,如果有差异就修正。
想不到好办法筛选,请教各位高手了,先谢了!
作者: CrLf    时间: 2013-7-16 22:34

如果 b.txt 的索引号 a.txt 都有的话,可以试试这样:
  1. @echo off
  2. call :setvar a.txt
  3. call :setvar b.txt
  4. setlocal enabledelayedexpansion
  5. for /f "tokens=1,2 delims=_" %%a in (a.txt) do echo;!ar_%%a_%%b!
  6. endlocal
  7. pause&exit
  8. :setvar
  9. for /f "delims=" %%a in (%~s1) do (
  10.    for /f "tokens=1,2 delims=_" %%b in ("%%a") do set ar_%%b_%%c=%%a
  11. )
复制代码

作者: terse    时间: 2013-7-16 22:42

回复 6# CrLf
按楼主的意思 估计b.txt里序列 a.txt会没有 也有改变 没有的补进去
我在想问题是B.txt多出的 添加到A.txt的那段 因为像一、中央立法 和  law01\ 这样的目录(我这里假设是目录)怎么处理
楼主表述不详细 写这样的代码 其实是体力活 尽可能的表述清楚 才使大家都轻松
作者: pan528    时间: 2013-7-17 16:58

回复  CrLf
按楼主的意思 估计b.txt里序列 a.txt会没有 也有改变 没有的补进去
我在想问题是B.txt多出的 ...
terse 发表于 2013-7-16 22:42


“一、中央立法”是a.txt文本中的目录子栏目
“law01\ ”是文件夹
b.txt 是更新了的文件夹与a.txt文本对应部分的结果。

按我的思路:
1、提取a.txt文本的序号部分,分别与四个文件夹(law01、law02、law03、law04)的文件序号比对,只要序号相同,就用文件夹中文本的文件名替换a.txt文本的相应部分;
2、提取a.txt文本的序号外的文件名部分,分别与四个文件夹(law01、law02、law03、law04)的序号外的文件名比对,只要序号外的文件名相同,就用文件夹中文本的文件名替换a.txt文本的相应部分;
通过上述二步达到更新a.txt文本的目的。
但试了一下,水平太低,代码不能完成,请高手指点。
作者: terse    时间: 2013-7-17 17:51

回复 8# pan528
是的我也知道相信其他人也知道比对后不同的写入a文件
因为2_12167。。。这个有是在一、中央立法 和 二、行政法规 子栏目之间
目录子栏目(一、中央立法....) 与 文件夹(law01...) 是否对应 都是一定数目吗
如若多了一个 2_12168_................. 这个在A文件里是没有的 是要看其所在的文件夹决定吗
还有A文件一般有多大 或大致有多少条目 文件小和大或许处理方式可以不一样
作者: CrLf    时间: 2013-7-17 18:14

想简化处理可以先排除重复的多余行,再排序(排序代码你已经有了):
  1. @echo off
  2. gawk -F"_" "!a[$1,$2]++" law01\b.txt law02\b.txt law03\b.txt law04\b.txt a.txt
  3. ::排序代码
  4. pause
复制代码
只要在除重时把 a.txt 放在最后,就会只保留 b.txt 的内容
作者: xxpinqz    时间: 2013-7-17 18:27

现在看出点门道了,例如:
1_1029721234_中华人民共和国澳门特别行政区第一届**推选委员会委员守则
这个是law01\目录下的一个文件的文件名?很是好奇带*号的文件是如何建的?

按8楼说法,把a.txt和law0?4个目录下的文件名同时分隔成两部分,只要有一部分不同,则用文件名替换a.txt对应内容?
作者: terse    时间: 2013-7-17 18:39

楼主是否还有种情况 就是 a文件里有b文件里没有的
序列是否只考虑一种
作者: pan528    时间: 2013-7-17 21:28

回复 11# xxpinqz

原文不是*号,是网站认为是敏感字,用*替换的。
作者: pan528    时间: 2013-7-17 21:30

回复 12# terse

这种情况正是要更新的,a.txt文本有的文件夹中没有,说明文件夹的文件发生了变化,因此需要更新。
作者: terse    时间: 2013-7-18 13:26

本帖最后由 terse 于 2013-7-18 21:31 编辑

回复 14# pan528
发现代码对于目录问题不完善
  1. @echo off&setlocal enabledelayedexpansion
  2. %1(for /f "tokens=1* delims=_" %%i in ('%~s0 : ^|sort') do echo;%%j)>a.txt&exit
  3. ::>b.txt dir /b
  4. (for /f "tokens=1-2 delims=_" %%i in ('findstr .*_.*_.* b.txt') do echo %%i_%%j_)>"%temp%\$"
  5. Findstr /ivbg:"%temp%\$" a.txt |findstr _.*_ >>b.txt
  6. del "%temp%\$"
  7. for /l %%a in (1 1 99) do set "k=!k! "
  8. for /f "tokens=1-2* delims=_" %%i in (b.txt) do  (
  9.     if "%%j" =="" (
  10.        if defined str1 (
  11.           echo !str1:~-99!_%%i
  12.        ) else echo !k!_%%i
  13.     ) else (
  14.         set "str1=!k!%%i"
  15.         set "str2=!k!%%j"
  16.         echo !str1:~-99!!str2:~-99!_%%i_%%j_%%k
  17.     )
  18. )
复制代码

作者: pan528    时间: 2013-7-18 21:11

回复 15# terse

没有通过,不知道错在哪里?
作者: pan528    时间: 2013-7-18 21:20

回复 6# CrLf

CrLf 的代码加上生成b.txt文本的命令就可以适用右边文本名发生了变化的情形:
  1. @echo off
  2. :: 加上生成b.txt文本的命令
  3. for /l %%i in (1,1,4) do (
  4. echo law0%%i
  5. cd law0%%i
  6. dir /b /o *.*
  7. cd..
  8. )>>b.txt
  9. :: CrLf 的原代码
  10. call :setvar a.txt
  11. call :setvar b.txt
  12. setlocal enabledelayedexpansion
  13. for /f "tokens=1,2 delims=_" %%a in (a.txt) do echo;!ar_%%a_%%b!>>c.txt
  14. endlocal
  15. pause&exit
  16. :setvar
  17. for /f "delims=" %%a in (%~s1) do (
  18.    for /f "tokens=1,2 delims=_" %%b in ("%%a") do set ar_%%b_%%c=%%a
  19. )
复制代码
上述代码,经过了测试。
谢谢CrLf 的原代码!
作者: terse    时间: 2013-7-18 21:36

回复 16# pan528
已经修正一下  我知道还有有个目录的问题 你把测试结果看下
作者: pan528    时间: 2013-7-18 22:29

回复 18# terse


    还是没有通过。
我把模拟的目录传上来。
方便的话,请你测试一下。
作者: pan528    时间: 2013-7-18 23:07

本帖最后由 pan528 于 2013-7-19 18:48 编辑

回复 6# CrLf

版主CrLf:能否解释一下你的代码?

我研究了好久,水平太低,没有搞懂。

我把你的代码变了一下形,运行是正常的:
  1. @echo off
  2. for /f "delims=" %%a in (a.txt) do (
  3. for /f "tokens=1,2 delims=_" %%b in ("%%a") do set %%b_%%c=%%a
  4. )
  5. for /f "delims=" %%i in (b.txt) do (
  6. for /f "tokens=1,2 delims=_" %%a in ("%%i") do set %%a_%%b=%%i
  7. )
  8. setlocal enabledelayedexpansion
  9. for /f "tokens=1,2 delims=_" %%x in (a.txt) do (
  10. echo;!%%x_%%y!
  11. )>>c.txt
  12. endlocal
  13. pause&exit
复制代码
变形后我仍没有搞明白:

1、前两小段设置的变量与第三段的关系

2、如果要将代码改为适合:文本名相同,而双位序号不同,用目录中的文本序号替换a.txt文本的双位序号。
如何修改。

请高手指教,先谢了!
作者: terse    时间: 2013-7-18 23:31

回复 20# pan528
还是不清楚目录是否要变更
作者: pan528    时间: 2013-7-19 16:34

回复 21# terse

谢谢回贴。

测试了一下,这个代码,实际结果等于:

dir 四个目录中的文件 + 数字排序,从效果上看,忽略了a.txt文本的比对。

我希望更新文本达到这样的效果:
以a.txt文本为基础,看看a.txt文本的文件名,比较四个目录中的文件,有什么变化:
1、与a.txt文本的双位序号相同的文件,文件名发生了变化,即修改文件名;
CrLf 的代码加上生成b.txt文本的命令就可以适用右边文本名发生了变化的情形。
2、与a.txt文本的文件名相同,双位序号发生了变化,即修改双位序号;
CrLf 的代码不知能否改成适合这种情况。
3、四个目录有的,而a.txt文本中即没有相同的序号,又没有相同的文件名,不导入a.txt文本。
4、a.txt文本的目录子项,如“一、中央立法”等,不能变动。

因此,希望你能再改一下代码。谢谢。
作者: pan528    时间: 2013-7-19 19:30

本帖最后由 pan528 于 2013-7-19 19:32 编辑
回复  CrLf

CrLf 的代码加上生成b.txt文本的命令就可以适用右边文本名发生了变化的情形:上述代码,经过 ...
pan528 发表于 2013-7-18 21:20



    简化了一下20楼根据 CrLf 改写代码:
  1. @echo off
  2. title 通过比对目录中的文件双位序号更新文本
  3. for /f "delims=" %%a in (a.txt) do (
  4. for /f "tokens=1,2 delims=_" %%b in ("%%a") do set %%b_%%c=%%a
  5. )
  6. for /f "delims=" %%i in ('dir /s /b /on') do (
  7. for /f "tokens=1,2 delims=_" %%a in ("%%~nxi") do set %%a_%%b=%%~nxi
  8. )
  9. setlocal enabledelayedexpansion
  10. for /f "tokens=1,2 delims=_" %%x in (a.txt) do (
  11. echo;!%%x_%%y!
  12. )>>New.txt
  13. endlocal
  14. pause&exit
复制代码
测试通过!
作者: terse    时间: 2013-7-20 00:38

本帖最后由 terse 于 2013-7-20 00:41 编辑

回复 22# pan528
上面给你代码 并不是你说的  dir 四个目录中的文件 + 数字排序 只是没看到
早这样述说 应该问题变的简单一点
前面以为你把目录有 A文件没的也要更新到A文件
去掉前面的A文件遍历 但效率不知道怎么样
还有遇到序列和文件名都变化 你要依据修改那个呢
  1. @echo off
  2. for /d %%a in (*) do (
  3.     for /f "tokens=1-2* delims=_" %%i in ('dir /b /a-d "%%a"') do (
  4.         set "%%i_%%j=%%k"
  5.         set "_%%k=%%i_%%j"
  6.     )
  7. )
  8. setlocal enabledelayedexpansion
  9. (for /f "tokens=1-2* delims=_" %%i in (a.txt) do (
  10.     if "!%%i_%%j!" == "" (
  11.        if "%%k" neq "" (
  12.           if "!_%%k!" neq "" (
  13.               echo !_%%k!_%%k&set "!_%%k!="
  14.           ) else echo %%i_%%j_%%k
  15.        ) else echo %%i
  16.     ) else echo %%i_%%j_!%%i_%%j!&set "_!%%i_%%j!="
  17. ))>new_a.txt
  18. pause
复制代码

作者: pan528    时间: 2013-7-20 11:05

回复 24# terse

测试通过!
非常谢谢你不厌其烦的解答!
代码完全符合全部要求。
对初学者来说比较好理解,只有好好学习了!
再次表示感谢!
作者: pan528    时间: 2013-7-20 12:05

回复 24# terse

这个代码的通用性也很好,如果序号只有一位,如:
一、中央立法
1_关于中华人民共和国国都、纪年、国歌、国旗的决议
10_全国人民代表大会常务委员会批准国务院关于华侨捐资兴办学校办法的决议
100_全国人民代表大会常务委员会关于海南省出席第七届全国人民代表大会代表团组成的决定
101_中华人民共和国进出口商品检验法
102_中华人民共和国传染病防治法
103_中华人民共和国行政诉讼法
102742_全国人民代表大会常务委员会关于中国银行业监督管理委员会履行原由中国人民银行履行的监督管理职责的决定
1029721234_中华人民共和国澳门特别行政区第一届XX推选委员会委员守则
二、行政法规
12167_国务院关于发布《中华人民共和国一九八七年国库券条例》的通知
12180_国务院关于违反财政法规处罚的暂行规定
12226_国家土地开发建设基金回收管理试行办法
12310_中共中央办公厅、国务院办公厅关于在国内公务活动中严禁用XX宴请和有关工作餐的规定
122765_全民所有制工业企业承包经营责任制暂行条例(修订)
1253070_中华人民共和国进出口关税条例

将代码相应修改即可通过:
  1. @echo off
  2. for /d %%a in (*) do (
  3.     for /f "tokens=1* delims=_" %%i in ('dir /b /a-d "%%a"') do (
  4.         set "%%i=%%j"
  5.         set "_%%j=%%i"
  6.     )
  7. )
  8. setlocal enabledelayedexpansion
  9. (for /f "tokens=1* delims=_" %%i in (a.txt) do (
  10.     if "!%%i!" == "" (
  11.        if "%%j" neq "" (
  12.           if "!_%%j!" neq "" (
  13.               echo !_%%j!_%%j&set "!_%%j!="
  14.           ) else echo %%i_%%j
  15.        ) else echo %%i
  16.     ) else echo %%i_!%%i!&set "_!%%i!="
  17. ))>new_a.txt
  18. pause
复制代码

作者: CrLf    时间: 2013-7-20 18:02

回复 26# pan528


    以后把要求在顶楼一次说清吧,大家都轻松




欢迎光临 批处理之家 (http://bbs.bathome.net/) Powered by Discuz! 7.2