Board logo

标题: [文本处理] 【已解决】批处理怎样找出序号重复的行? [打印本页]

作者: pan528    时间: 2013-7-14 17:13     标题: 【已解决】批处理怎样找出序号重复的行?

本帖最后由 pan528 于 2013-7-16 13:01 编辑

一个文本,序号相同,但其他内容(如第二段)不同。如下例:
  1. 142102_最高人民法院关于对被监禁或被劳动教养的人提起的民事诉讼如何确定案件管辖问题的批复
  2. 142640_最高人民法院、最高人民**关于废止部分**解释和规范性文件的决定
  3. 143183_最高人民法院印发《关于大力推广巡回审判方便人民群众诉讼的意见》的通知
  4. 143183_关于大力推广巡回审判方便人民群众诉讼的意见
  5. 143184_最高人民法院印发《关于处理自首和立功若干具体问题的意见》的通知
  6. 143267_最高人民法院关于审理涉台民商事案件法律适用问题的规定
  7. 143267_涉台民商事案件法律适用问题
  8. 143356_最高人民法院、最高人民**、**部、**部关于限令拐卖妇女儿童犯罪人员投案自首的通告
  9. 143464_最高人民法院关于对因资不抵债无法继续办学被终止的民办学校如何组织清算问题的批复
  10. 143591_最高人民法院关于审理非法集资刑事案件具体应用法律若干问题的解释
  11. 143885_最高人民法院、最高人民**、**部印发《关于办理侵犯知识产权刑事案件适用法律若干问题的意见》的通知
  12. 144084_最高人民法院关于审理期货纠纷案件若干问题的规定(二)
  13. 144560_最高人民**关于对涉嫌盗窃的不满16周岁未成年人采取刑事拘留强制措施是否违法问题的批复
  14. 144873_最高人民法院印发《关于规范上下级人民法院审判业务关系的若干意见》的通知
  15. 144955_最高人民法院关于判决生效后当事人将判决确认的债权转让债权受让人对该判决不服提出再审申请人民法院是否受理问题的批复
复制代码
重号行,导出文本如下:
  1. 143183_最高人民法院印发《关于大力推广巡回审判方便人民群众诉讼的意见》的通知
  2. 143183_关于大力推广巡回审判方便人民群众诉讼的意见
  3. 143267_最高人民法院关于审理涉台民商事案件法律适用问题的规定
  4. 143267_涉台民商事案件法律适用问题
复制代码
代码如何设计?
作者: CrLf    时间: 2013-7-14 17:37

一个方案:
  1. @echo off&setlocal enabledelayedexpansion
  2. for /f "delims=_" %%a in (a.txt) do set /a $%%a$+=1
  3. for /f "delims=$" %%a in ('set $^|findstr /e "$=2"') do set "key=!key! %%a"
  4. findstr /b "!key!" a.txt
  5. pause
复制代码

作者: apang    时间: 2013-7-14 18:37

来个vbs,闲的。
  1. Set fso = CreateObject("Scripting.FileSystemObject")
  2. Set dic = CreateObject("Scripting.Dictionary")
  3. Set file = fso.OpenTextFile("a.txt")
  4. Do until file.AtEndOfStream
  5.     str = file.ReadLine
  6.     a = Left(str,InStr(str,"_"))
  7.     If not dic.Exists(a) Then
  8.         dic.Add a,str
  9.     Else dic.Item(a) = dic.Item(a) & vbCrLf & str
  10.     End If
  11. Loop
  12. For Each b in dic.Keys
  13.     If InStr(dic.Item(b),vbCrLf) Then
  14.         fso.OpenTextFile("b.txt",8,True).WriteLine dic.Item(b)
  15.     End If
  16. Next
复制代码

作者: CrLf    时间: 2013-7-14 18:58

也可以这样:
  1. @echo off
  2. (sort | uniq -w 7 -D)<a.txt
  3. pause
复制代码

作者: CrLf    时间: 2013-7-14 19:07

还看到一个精巧的 awk 方案,小改如下:
  1. gawk -F"_" "NR==FNR{a[$1]++}NR>FNR&&a[$1]>1" a.t
  2. xt a.txt
复制代码

作者: terse    时间: 2013-7-14 19:30

也来个
  1. @echo off
  2. (for /f "tokens=1 delims=_" %%i in (1.txt) do if defined $%%i (echo %%i)else set "$%%i=A")>$.t
  3. findstr /ibg:$.t 1.txt
  4. pause
复制代码

作者: pan528    时间: 2013-7-15 12:58

回复 3# apang

谢谢相助!已通过测试,效率也挺高的。请问如果序号是“x_xxx_“结构,代码要怎样改一下?
作者: pan528    时间: 2013-7-15 13:03

回复 6# terse

拿复杂一点的文本一试,只找出了部分重复的行,有的只能前一行不能输出后一行。不知代码的问题出在哪。
作者: pan528    时间: 2013-7-15 13:05

回复 2# CrLf

我将最后一行改为”findstr /b "!key!" a.txt>>b.txt“仍不能输出结果。不知错在哪里。
作者: terse    时间: 2013-7-15 13:50

回复 8# pan528
暂不清楚问题出在那
先用记事本打开 $.t 检查里面重复号是否有遗漏
另 检查 $.t 里面的重复号在txt 文本里是否在行起始位置
作者: apang    时间: 2013-7-15 16:39

回复 7# pan528


    x_xxx_ 由数字和下划线组成
  1. Set fso = CreateObject("Scripting.FileSystemObject")
  2. Set dic = CreateObject("Scripting.Dictionary")
  3. Set file = fso.OpenTextFile("a.txt")
  4. Do until file.AtEndOfStream
  5.     str = file.ReadLine
  6.     a = RegEx(str)
  7.     If str <> a Then
  8.         If not dic.Exists(a) Then
  9.             dic.Add a,str
  10.         Else dic.Item(a) = dic.Item(a) & vbCrLf & str
  11.         End If
  12.     End If
  13. Loop
  14. For Each b in dic.Keys
  15.     If InStr(dic.Item(b),vbCrLf) Then
  16.         fso.OpenTextFile("b.txt",8,True).WriteLine dic.Item(b)
  17.     End If
  18. Next
  19. Function RegEx(str)
  20.     Set re = New RegExp
  21.     re.Pattern = "^\s*((\d+_)+).*$"
  22.     RegEx = re.Replace(str,"$1")
  23. End Function
复制代码

作者: CrLf    时间: 2013-7-15 17:26

回复 7# pan528


    可否贴出样本
作者: wskwfkbdn    时间: 2013-7-15 21:34

@echo off
for /f "tokens=1 delims=_" %%i in (a.txt) do echo %%i>>b.txt
for /f %%i in ('uniq -d b.txt') do findstr "%%i" a.txt
del/f/q b.txt 2>nul
pause

findstr /n "%%i" a.txt  如想显示行号可以加上 /n 开关
作者: pan528    时间: 2013-7-16 12:43

回复 6# terse

试了好多次,把问题查出来了,主要有二点:
一是“$.t”文件在退出时没有删除,导致第二次运行出错;
二是“$%%i”后面没有加下划线,以至当前面序号相同时,相关的序号都当成了同序号。如:52_、520_、521_、522_、等。
但还是感谢你提供了一个巧妙的思路,而且是纯DOS的,不需第三方软件支持的命令。再次表示谢谢。
为了适合双位序号,如 XX_XXXXXX_ 的格式,我将代码修改如下,已经过测试:
  1. @echo off
  2. title 导出序号重复的行
  3. echo 正在导出序号重复的行 ...
  4. (for /f "tokens=1-2* delims=_" %%i in (1.txt) do if defined $%%i_%%j_ (echo %%i_%%j_)else set "$%%i_%%j_=A")>$.t
  5. findstr /ibg:$.t 1.txt>>3.txt
  6. del/f/q $.t 2>nul
  7. pause
复制代码

作者: pan528    时间: 2013-7-16 13:00

回复 13# wskwfkbdn

谢谢,通过了检测。
作者: xxpinqz    时间: 2013-7-16 13:19

lz也发过不少帖子了,应该懂的:最基本的把问题交代清楚,提供有针对性的例子。不然谁会去判断你是否有两组或更多组序号呢
作者: pan528    时间: 2013-7-16 14:38

回复 16# xxpinqz

接受批评。
但双组序号是后加的条件。
作者: apang    时间: 2013-7-16 14:48

回复 17# pan528


    11楼你试过没有?
作者: pan528    时间: 2013-7-16 15:58

回复 11# apang

通过检测,谢谢了!VBS效率就是高!




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