Board logo

标题: [文本处理] [已解决]批处理如何只对目录的子项按降序排序,而其他项顺序不变? [打印本页]

作者: pan528    时间: 2013-5-19 12:42     标题: [已解决]批处理如何只对目录的子项按降序排序,而其他项顺序不变?

本帖最后由 pan528 于 2013-5-27 07:15 编辑

有一个目录结构如下:
0100000000_宪法
0101000000_一、宪法与修正案
2004-03-14_中华人民共和国宪法(2004修正)
1982-12-04_中华人民共和国宪法(1982)
1988-04-12_中华人民共和国宪法修正案(1988)
1993-03-29_中华人民共和国宪法修正案(1993)
1999-03-15_中华人民共和国宪法修正案(1999)
2004-03-14_中华人民共和国宪法修正案(2004)
0102000000_二、与宪法相关法
0102010000_(一)立法与监督
0102010100_1、立法法
2000-07-01_中华人民共和国立法法(2000)
1985-04-10_全国人民代表大会关于授权国务院在经济体制改革和对外开放方面可以制定暂行的规定或者条例的决定
1996-04-26_全国人民代表大会常务委员会法制工作委员会关于地方性法规对法律中没有规定的行政处罚行为可否作出补充规定问题的答复
1996-11-08_全国人民代表大会常务委员会法制工作委员会关于如何掌握地方性法规清理标准问题的答复
2000-10-19_全国人大常委会法制工作委员会关于省人大能否对全省地方立法工作程序进行统一规定的答复
2000-11-20_全国人民代表大会常务委员会法制工作委员会关于制定法律、法规条件不成熟能否先制定部门规章,涉及外交、外贸政策的部门规章能否不向社会公开的答复
2000-12-28_全国人民代表大会常务委员会法制工作委员会关于地方人民法院、人民**能否提出地方性法规案的答复
0102010200_2、法律的修改与废止
2009-08-27_全国人民代表大会常务委员会关于修改部分法律的决定(2009)
2009-06-27_全国人民代表大会常务委员会关于废止部分法律的决定(2009)
0102010300_3、监督法
2007-01-01_中华人民共和国各级人民代表大会常务委员会监督法(2006)
0102020000_(二)组织法与选举法
0102020100_1、组织法
1982-12-10_中华人民共和国全国人民代表大会组织法(1982)
2004-10-27_中华人民共和国地方各级人民代表大会和地方各级人民**组织法(2004修正)
1982-12-10_中华人民共和国国务院组织法(1982)
2007-01-01_中华人民共和国人民法院组织法(2006修正)
1983-09-02_中华人民共和国人民**组织法(1983修正)
1990-01-01_中华人民共和国城市居民委员会组织法(1989)
1998-11-04_中华人民共和国村民委员会组织法(2010修订)
0102020200_2、选举法
2010-03-14_中华人民共和国全国人民代表大会和地方各级人民代表大会选举法(2010修正)
1983-03-05_全国人民代表大会常务委员会关于县级以下人民代表大会代表直接选举的若干规定
0102020300_3、代表法
2010-10-28_中华人民共和国全国人民代表大会和地方各级人民代表大会代表法(2010修正)
2004-10-27_全国人民代表大会常务委员会关于县、乡两级人民代表大会代表选举时间的决定(2004)
2012-06-30_中国人民解放军选举全国人民代表大会和县级以上地方各级人民代表大会代表的办法(2012修正)
...
排为降序后,为:
0100000000_宪法
0101000000_一、宪法与修正案
2004-03-14_中华人民共和国宪法(2004修正)
2004-03-14_中华人民共和国宪法修正案(2004)
1999-03-15_中华人民共和国宪法修正案(1999)
1993-03-29_中华人民共和国宪法修正案(1993)
1988-04-12_中华人民共和国宪法修正案(1988)
1982-12-04_中华人民共和国宪法(1982)
0102000000_二、与宪法相关法
0102010000_(一)立法与监督
0102010100_1、立法法
2000-12-28_全国人民代表大会常务委员会法制工作委员会关于地方人民法院、人民**能否提出地方性法规案的答复
2000-11-20_全国人民代表大会常务委员会法制工作委员会关于制定法律、法规条件不成熟能否先制定部门规章,涉及外交、外贸政策的部门规章能否不向社会公开的答复
2000-07-01_中华人民共和国立法法(2000)
2000-10-19_全国人大常委会法制工作委员会关于省人大能否对全省地方立法工作程序进行统一规定的答复
1996-11-08_全国人民代表大会常务委员会法制工作委员会关于如何掌握地方性法规清理标准问题的答复
1996-04-26_全国人民代表大会常务委员会法制工作委员会关于地方性法规对法律中没有规定的行政处罚行为可否作出补充规定问题的答复
1985-04-10_全国人民代表大会关于授权国务院在经济体制改革和对外开放方面可以制定暂行的规定或者条例的决定
0102010200_2、法律的修改与废止
2009-08-27_全国人民代表大会常务委员会关于修改部分法律的决定(2009)
2009-06-27_全国人民代表大会常务委员会关于废止部分法律的决定(2009)
0102010300_3、监督法
2007-01-01_中华人民共和国各级人民代表大会常务委员会监督法(2006)
0102020000_(二)组织法与选举法
0102020100_1、组织法
2007-01-01_中华人民共和国人民法院组织法(2006修正)
2004-10-27_中华人民共和国地方各级人民代表大会和地方各级人民**组织法(2004修正)
1998-11-04_中华人民共和国村民委员会组织法(2010修订)
1990-01-01_中华人民共和国城市居民委员会组织法(1989)
1983-09-02_中华人民共和国人民**组织法(1983修正)
1982-12-10_中华人民共和国全国人民代表大会组织法(1982)
1982-12-10_中华人民共和国国务院组织法(1982)
0102020200_2、选举法
2010-03-14_中华人民共和国全国人民代表大会和地方各级人民代表大会选举法(2010修正)
1983-03-05_全国人民代表大会常务委员会关于县级以下人民代表大会代表直接选举的若干规定
0102020300_3、代表法
2012-06-30_中国人民解放军选举全国人民代表大会和县级以上地方各级人民代表大会代表的办法(2012修正)
2010-10-28_中华人民共和国全国人民代表大会和地方各级人民代表大会代表法(2010修正)
2004-10-27_全国人民代表大会常务委员会关于县、乡两级人民代表大会代表选举时间的决定(2004)

即、目录的子项按降序排序,而其他项顺序不变。
请高手指点。
作者: 林小七    时间: 2013-5-19 14:32

sort..你去看看......
作者: terse    时间: 2013-5-19 14:32

这个是DIR 结果吗  怎么看子项
另: 子项按目录名 DIR 试下
作者: pan528    时间: 2013-5-24 07:00

很报歉,是我表达不准确。上述例子是一个文本。是文本排列的行,要求含有序列号的行在排序时位置不能变。只对其它子项进行降序排列。
作者: pan528    时间: 2013-5-24 07:19

问题的难点是:如果用sort命令降序,含有零开始的十位数序列号的行也会降序排列。这是我不希望发生的。
作者: apang    时间: 2013-5-24 13:41

vbs 试试?
  1. Set fso = CreateObject("Scripting.FileSystemObject")
  2. text = fso.OpenTextFile("a.txt",1).ReadAll
  3. Set re = New RegExp
  4. re.Pattern = "(\d{4}-\d{2}-\d{2}_.*(?:[\r\n]*))+"
  5. re.Global = True
  6. For Each a in re.Execute(text)
  7.     text = Replace(text,a,Sort(Split(a,vbCrLf)))
  8. next
  9. Function Sort(ar)
  10.     For i = 0 to UBound(ar)-1
  11.         For j = i + 1 to UBound(ar)
  12.             If ar(i) < ar(j) Then
  13.                 tmp = ar(i) : ar(i) = ar(j) : ar(j) = tmp
  14.             End If
  15.         Next
  16.     Next
  17.     Sort = Join(ar,vbCrLf)
  18. End Function
  19. fso.CreateTextFile("b.txt",True).Write text
  20. MsgBox "OK"
复制代码

作者: pan528    时间: 2013-5-24 17:43

谢谢楼上,这个vbs命令有效,可以进行降序排列。但我希望用DOS写一个这样的程序,请高手指点。
作者: CrLf    时间: 2013-5-24 18:31

需要第三方工具 gawk:
  1. @gawk -F"[_-]" "{if(length($1)>4){qz=$1};ar[i++]=qz \"_\" $0}END{n=asort(ar);for (i=1;i<=n;i++){sub(/[0-9]*_/,\"\",ar[i]);print ar[i]}}"<"输入文件.txt">"输出文件.txt"
复制代码

作者: pan528    时间: 2013-5-26 09:22

本帖最后由 pan528 于 2013-5-26 09:50 编辑

谢谢楼上的回贴,但代码得出的结果是升序的排列,我想要的是子项降序排列,纯DOS的批处理。如果是升序,下面的批处理也可以搞定:
  1. set /p Files=请输入要排序的文件:
  2. echo 正在对文本中的子项行进行排序,请稍候 ...
  3. setlocal enabledelayedexpansion
  4. for /f "tokens=1* delims=_" %%i in (%Files%) do (
  5. set m=%%i
  6. if "!m:~0,1!" == "0" set x=%%i echo !m:~0,10!_%%i_%%j>>N%Files%
  7. echo !x:~0,10!_%%i_%%j>>N%Files%
  8. )
  9. endlocal
  10. sort N%Files%>>~y.txt
  11. for /f "tokens=1* delims=_" %%i in (~y.txt) do echo %%j>>OK_%Files%
  12. del ~*.txt
  13. del N%Files%
  14. start OK_%Files%
复制代码

作者: xxpinqz    时间: 2013-5-26 12:56

本帖最后由 xxpinqz 于 2013-5-26 13:02 编辑

和上面的一堆代码相比,这和蜗牛一样:
  1. @echo off&setlocal enabledelayedexpansion
  2. set "file=a.txt"
  3. cd.>tmp
  4. (
  5.    for /f "delims=" %%a in (%file%) do (
  6.       set "str=%%a"
  7.       if not "!str:~,1!"=="0" (
  8.         >>tmp echo %%a
  9.       ) else (
  10.       sort tmp|sort /+1000&cd.>tmp&echo %%a
  11.       )
  12.    )
  13.    sort tmp|sort /+1000
  14. )>b.txt
  15. del tmp&start b.txt
复制代码
在这代码上传不能出现$&,会被替换掉
作者: CrLf    时间: 2013-5-26 16:35

回复 9# pan528


    改改就好了嘛
  1. @gawk -F"[_-]" "BEGIN{qz=99999999}{flag=0;if(length($1)>4){qz--;flag=1};ar[i++]=qz flag \"_\" $0}END{n=asort(ar);for (i=n;i>0;i--){sub(/[0-9]*_/,\"\",ar[i]);print ar[i]}}"<"输入文件.txt">"输出文件.txt"
复制代码

作者: CrLf    时间: 2013-5-26 16:52

纯批也可以,就是会慢一些
  1. @echo off
  2. if "%~1"=="" goto fun
  3. set Files=%~snx1
  4. echo 正在对文本中的子项行进行排序,请稍候 ...
  5. (for /f "tokens=1* delims=_" %%i in ('%0^|sort /r') do echo %%j)>OK_%Files%
  6. start OK_%Files%
  7. pause&exit
  8. :fun
  9. set qz=99999999
  10. for /f "delims=" %%i in (%Files%) do (
  11. set "flag=0"
  12. set "m=%%i"
  13. setlocal enabledelayedexpansion
  14. if "!m:~4,1!" neq "-" (
  15. set /a qz-=flag=1
  16. )
  17. for /f "tokens=1,2*delims=_" %%a in ("!qz!_!flag!_!m!") do (
  18. endlocal
  19. set /a qz=%%a,flag=%%b
  20. set m=%%c
  21. echo %%a%%b_%%c
  22. )
  23. )
复制代码

作者: apang    时间: 2013-5-26 19:02

  1. @echo off
  2. (for /f "delims=" %%a in (a.txt) do (
  3.     set "str=%%a"
  4.     setlocal enabledelayedexpansion
  5.     if "!str:~,1!"=="0" (
  6.         endlocal
  7.         if exist $ sort /r $&del $
  8.         echo,%%a
  9.     ) else endlocal&echo,%%a>>$
  10. ))>b.txt
  11. if exist $ sort /r $>>b.txt&del $
复制代码

作者: xxpinqz    时间: 2013-5-26 23:54

回复 13# apang
原来可以直接sort /r,谢谢!!
作者: xxpinqz    时间: 2013-5-27 00:03

回复 12# CrLf
基础太差了,看了好久才看出来,一直没从想到一条语句其实也可以是一堆代码,
一直纠结在%0^|sort /r,这怎么是把批处理内容反向排序。
还傻乎乎的把批处理 sort /r一下再去执行一次~~~~
作者: pan528    时间: 2013-5-27 07:12

谢谢各位高手,喜出望外,提供了这么代码和思路!
测试了一下,十楼以下的四个代码都通过了测试,CrLf 的代码效率最高,gawk效率高的惊人,看来第三方软件,有时也值得一用。CrLf 的纯DOS代码运行也是最快的。
再次表示感谢!
作者: CrLf    时间: 2013-5-27 17:18

回复 15# xxpinqz


    那是 terse 的绝招,被偷学了,嘿嘿
作者: pan528    时间: 2013-5-27 18:41

本帖最后由 pan528 于 2013-5-27 18:45 编辑

按crlf的程序结构,改造了一下我的升序的批命令,效率提高了许多:
  1. @echo off
  2. title 对目录文本按升序排列
  3. if "%~1"=="" goto:Ascending
  4. set File=%~snx1
  5. if exist A%File% del A%File%
  6. echo 正在对文本中的子项按升序排列,请稍候 ...
  7. (for /f "tokens=1* delims=_" %%i in ('%0^|sort') do echo %%j)>A%File%
  8. start A%File%
  9. exit /b
  10. :Ascending
  11. setlocal enabledelayedexpansion
  12. for /f "tokens=1* delims=_" %%i in (%File%) do (
  13. set m=%%i
  14. if "!m:~0,1!" == "0" set x=%%i echo !m:~0,10!_%%i_%%j
  15. echo !x:~0,10!_%%i_%%j
  16. )
  17. endlocal
  18. goto :eof
复制代码
但想请教一下crlf,我没有理解“if "%~1"=="" goto fun”,这段语句,拖拽时,“"%~1"=="" ”是怎么回事?
作者: xxpinqz    时间: 2013-5-27 22:09

本帖最后由 xxpinqz 于 2013-5-27 22:23 编辑
  1. @echo off&setlocal enabledelayedexpansion
  2. title 对目录文本按升序排列
  3. if "%~1"=="" goto :eof
  4. set File=%~snx1
  5. (for /f "tokens=1* delims=_" %%i in (%File%) do (
  6.         set m=%%i
  7.         if "!m:~0,1!" == "0" set x=%%i
  8.         echo !x:~0,10!_%%i_%%j
  9. ))>$
  10. echo 正在对文本中的子项按升序排列,请稍候 ...
  11. (for /f "tokens=1* delims=_" %%i in ('sort $') do echo %%j)>A%File%
  12. start A%File%
  13. del $&exit /b
复制代码
你这样理解就很简单了




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