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

[文本处理] 批处理如何将目录行索引切分为目录列索引

本帖最后由 pan528 于 2013-6-1 11:12 编辑

材料条件和要求:
1、目录行索引是不断增加的,因此是不确定;
2、考虑通用性,目录列也是可调整的,有一定范围的,如3-15列中的一个。

可能的问题:
1、一定的目录行索引切分为指定的目录列索引,可能不被整除。即需要补空格才能使各列对齐;
2、从阅读习惯上看,对最后一列补齐比较符合一般情况。但:
34行切成11列、28行切成9列、12行切成5列等等情形,光补最后一列就会成为空列。这时就要采用补齐其他列的方法来对齐 ...

材料举例:
目录行索引
  1. 最高人民法院公报
  2. 1985年
  3.  第01期
  4.  第02期
  5.  第03期
  6.  第04期
  7. 1986年
  8.  第01期
  9.  第02期
  10.  第03期
  11.  第04期
  12. 1987年
  13.  第01期
  14.  第02期
  15.  第03期
  16.  第04期
  17. 1988年
  18.  第01期
  19.  第02期
  20.  第03期
  21.  第04期
  22. 1989年
  23.  第01期
  24.  第02期
  25.  第03期
  26.  第04期
复制代码
目录列索引(切分为五列)

最高人民法院公报                1986年                         第01期                         第02期                         第03期       
1985年                         第01期                         第02期                         第03期                         第04期       
 第01期                         第02期                         第03期                         第04期       
 第02期                         第03期                         第04期                        1989年
 第03期                         第04期                        1988年                         第01期       
 第04期                        1987年                         第01期                         第02期       



目录列索引(切分为三列)
  1. 最高人民法院公报  第03期  第02期
  2. 1985年  第04期  第03期
  3.  第01期 1987年  第04期
  4.  第02期  第01期 1989年
  5.  第03期  第02期  第01期
  6.  第04期  第03期  第02期
  7. 1986年  第04期  第03期
  8.  第01期 1988年  第04期
  9.  第02期  第01期
复制代码
目录列索引(切分为五列12/5的特殊情形)
最高人民法院公报                 第02期                        1986年                         第02期                         第04期       
1985年                         第03期                         第01期                         第03期                        1987年
 第01期                         第04期

本帖最后由 terse 于 2013-6-9 23:36 编辑

不是列大于行 3分吗
余数: 34/9 应该余7  7大于行4啊
这里的余数是否 应该  34/4 余 2 ?

你30楼的描述
..三分法就是:在上面二分法的基础上,对切分列数小于每列行数的情形,用另一种方法排列,即把所有空格放在最后一列。...

TOP

回复 49# terse
34/11,34/9都通过了,但是仍二分法,不是三分法:

二分法:
1       5       9       13      17      21      25      29      32
2       6       10      14      18      22      26      30      33
3       7       11      15      19      23      27      31      34
4       8       12      16      20      24      28

三分法:(余数小于每列的行数时,空行全部放在最后一列)
1       5       9       13      17      21      25      29      33
2       6       10      14      18      22      26      30      34
3       7       11      15      19      23      27      31
4       8       12      16      20      24      28      32

TOP

本帖最后由 terse 于 2013-6-8 14:10 编辑

有点给数字绕晕的感觉
只能再试着简化下 思路闭塞 总不能突破
  1. @echo off&setlocal enabledelayedexpansion
  2. %1 %0 :|more /t32 >n.txt&exit
  3. set "file=test.txt"
  4. for /f "delims=U" %%a in ('cmd /u /c echo 唉') do set "tab=%%a"
  5. for /f "usebackq tokens=*" %%i in ("%file%") do set /a N+=1&set #!N!=%%i
  6. set L=9
  7. set /a "h=(n+l-1)/l,i=^!(~-l/h),j=^!i*(n%%l)*h+i*n"
  8. for /l %%i in (1 1 !n!) do (
  9.     set /a "i=^!(~-%%i/j),m=(~-%%i-(^!i*j))%%(~-h+i)+1"
  10.     for %%j in (!m!) do set "$%%j=!$%%j!%tab%!#%%i!"
  11. )
  12. for /l %%i in (1 1 !h!) do for /f "tokens=*" %%j in ("!$%%i!") do echo %%j
复制代码
既然MORE 最后回车肯定有 没必要再处理它了吧
  1. @echo off&setlocal enabledelayedexpansion
  2. %1 %0 :|more /t32 >n.txt&exit
  3. set "file=test.txt"
  4. for /f "delims=U" %%a in ('cmd /u /c echo 唉') do set "tab=%%a"
  5. for /f "usebackq tokens=*" %%i in ("%file%") do set /a N+=1&set #!N!=%%i
  6. set L=9
  7. set /a "h=(n+l-1)/l,j=n%%l,i=^!(l/h)"
  8. if !j! equ 0 (set j=!n!)else set /a "j=~-l*h*i+j*h"
  9. for /l %%i in (1 1 !n!) do (
  10.     set /a "i=^!(~-%%i/j),m=(~-%%i-(^!i*j))%%(~-h+i)+1"
  11.     for %%j in (!m!) do set "$%%j=!$%%j!%tab%!#%%i!"
  12. )
  13. for /l %%i in (1 1 !h!) do for /f "tokens=*" %%j in ("!$%%i!") do echo %%j
复制代码

TOP

回复 47# terse

34/9通过了,34/11又变成了9列,我想算法可能有缺陷或漏洞 ...

TOP

回复 30# pan528
也许代码的算法有误
这样吧 你把44楼代码里  if !h! lss !l! set /a j=(n%%l)*h 这里的 LSS 改为GTR 看是否你要的
  1. @echo off&setlocal enabledelayedexpansion
  2. %1 %0 :|more /t32 >n.txt&exit
  3. set L=9
  4. set "file=test.txt"
  5. for /f "delims=U" %%a in ('cmd /u /c echo 唉') do set "tab=%%a"
  6. for /f "usebackq tokens=*" %%i in ("%file%") do set /a N+=1&set #!N!=%%i
  7. set /a h=(n+l-1)/l
  8. if !h! gtr !l! set /a j=(n%%l)*h
  9. if !j! equ 0 set j=!n!
  10. for /l %%i in (1 1 %n%) do (
  11.     set /a "i=^!(~-%%i/j),m=(~-%%i-(^!i*j))%%(~-H+i)+1"
  12.     for %%j in (!m!) do set "$%%j=!$%%j!%tab%!#%%i!"
  13. )
  14. for /l %%i in (1 1 %h%) do for /f "tokens=*" %%j in ("!$%%i!") do echo %%j
复制代码
代码处理流程是这样的
当行大于列 或 行小于列时的输出是不一样的

TOP

你们的代码太精炼了,我许多方面都没有看明白。
我以前写了一个切分文本的代码,很菜。代码很长,很繁琐,方法也简单,拿出来请各位高手改改。
但,我试过好多次,没有出错过。
  1. :: 代码代号含义:
  2. :: k=文本总行数
  3. :: cut=切分的列数
  4. :: x=k/c=每列的行数
  5. :: r=remainder=余数行=k-cx
  6. :: ak=总添加的行数=(cut*(x+1))-k
  7. :: s=记录当前文件需要排列的行数=x或(x+1)
  8. :: s2=少行列=s-ak
  9. :: n=记录当前列输出到第几行
  10. :: m=记录当前输出到第几个文件
  11. @echo off
  12. title 切分文本程序(三分法)
  13. set file=a
  14. set Cut=9
  15. setlocal enabledelayedexpansion
  16. for /f "delims=" %%a in (%file%.txt) do set/a k+=1
  17. set /a x=%k%/%Cut%
  18. set /a r=%k%-%Cut%*%x%
  19. set /a ak=(%Cut%*(%x%+1))-%k%
  20. set m=
  21. set m=1
  22. set n=
  23. for /f "delims=" %%i in (%file%.txt) do (
  24. set /a n+=1
  25. if !r! leq 0 (
  26. set /a s=%x%
  27. if !n! leq !s! echo %%i>>%file%_!m!.txt
  28. if !n! equ !s! set n=0 & set /a m+=1
  29. ) else (
  30. set /a s=%x%+1
  31. if !ak! lss !s! (
  32. if !n! leq !s! echo %%i>>%file%_!m!.txt
  33. if !n! equ !s! set n=0 & set /a m+=1
  34. if !m! equ !cut! set /a s2=!s!-!ak!
  35. if !n! equ !s2! for /l %%i in (1,1,%ak%) do echo.>>%file%_!cut!.txt
  36. ) else (
  37. if !m! leq !r! (
  38. if !n! leq !s! echo %%i>>%file%_!m!.txt
  39. if !n! equ !s! set n=0 & set /a m+=1
  40. ) else (
  41. if !m! gtr !r! if !n! leq !x! echo %%i>>%file%_!m!.txt
  42. if !m! gtr !r! if !n! equ !x! echo.>>%file%_!m!.txt
  43. if !n! equ !x! set n=0 & set /a m+=1
  44. )
  45. )
  46. )
  47. )
  48. endlocal
  49. goto:eof
复制代码

TOP

回复 44# terse

回车没有剔除,我还发现一个新问题:所有代码在34/9时都变成了二分法!即:
1    5    9    13   17   21   25   29   32
2    6    10   14   18   22   26   30   33
3    7    11   15   19   23   27   31   34
4    8    12   16   20   24   28
而三分法应为:
1    5    9    13   17   21   25   29   33
2    6    10   14   18   22   26   30   34
3    7    11   15   19   23   27   31
4    8    12   16   20   24   28   32
我怀疑是算法有问题。
各位高手找找原因吧。

TOP

你是指最后的回车行是MORE留下的吧
代码再少点变量
另补上exit
  1. @echo off&setlocal enabledelayedexpansion
  2. %1 %0 :|more /t32 >n.txt&exit
  3. set L=9
  4. set "file=a.txt"
  5. for /f "delims=U" %%a in ('cmd /u /c echo 唉') do set "tab=%%a"
  6. for /f "usebackq tokens=*" %%i in ("%file%") do set /a N+=1&set #!N!=%%i
  7. set /a h=(n+l-1)/l,j=n
  8. if !h! lss !l! set /a j=(n%%l)*h
  9. for /l %%i in (1 1 %n%) do (
  10.     set /a "i=^!(~-%%i/j),m=(~-%%i-(^!i*j))%%(~-H+i)+1"
  11.     for %%j in (!m!) do set "$%%j=!$%%j!%tab%!#%%i!"
  12. )
  13. for /l %%i in (1 1 %h%) do for /f "tokens=*" %%j in ("!$%%i!") do echo %%j
复制代码

TOP

回复 41# terse

测试通过!是三分法。不过最后多了一个回车,不知问题出在哪?

TOP

唉 惭愧我的理解力  但楼主的表达也太那个了  
都和我一样 国语学得不好

TOP

回复 40# xxpinqz
再仔细回看前面 猜真这次应该理解了
先粗糙一个
感觉代码写得太啰嗦   等下再看有 优化的可能不
  1. @echo off&setlocal enabledelayedexpansion
  2. %1 %0 REM|more /t32 >n.txt
  3. set L=5
  4. set "file=a1.txt"
  5. for /f "delims=U" %%a in ('cmd /u /c echo 唉') do set "tab=%%a"
  6. for /f "usebackq tokens=*" %%i in ("%file%") do set /a N+=1&set #!N!=%%i
  7. set /a h=(n+l-1)/l,j=n,i=1
  8. if !h! lss !l! set /a j=(n%%l)*H
  9. for /l %%i in (1 1 %n%) do (
  10.     set /a "t=^!^!(~-%%i/j)"
  11.     set /a "m=(~-%%i-(t*j))%%(~-H+i*^!t)+1"
  12.     for %%j in (!m!) do set "$%%j=!$%%j!%tab%!#%%i!"
  13. )
  14. for /l %%i in (1 1 %h%) do for /f "tokens=*" %%j in ("!$%%i!") do echo %%j
复制代码

TOP

回复 39# terse
话说我的数学就是加减乘除 ,所以算法吃不透,目测26楼代码是按输完一列再接着输下一列的按顺序输出
所以判断是否所谓三分也应该要用n/l来判断,而非0。
扯了3页,就下面两句是亮点:
8楼的set /a 行数=(n+列数-1)/ 列数
26楼的set /a "m=(%%i--~j)%%_i+1"
向两位高手致敬~~
初学BAT,非专业。代码不适当之处还望前辈们多多指点。在此表示感谢!

TOP

我目前 最直观的解  set /a 行=(总行+列-1)/列,余=(总行%%列)*行
得到 行 和 余的值
只要在 FOR 循环  判断总行 和 余 关系 应该够解了吧

TOP

我早先是靠测试弄懂了楼主的规则,但是没有好的思路,想法太繁琐,应该有更好的就题解题算法,目测 plp626 能手到擒来

TOP

返回列表