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

[文本处理] 【已解决】批处理:批量提取特定位置的数据

文件夹C:/文本1/ 内有210个txt文本,分别命名为001-210.txt。每个txt文本内有两行数据,格式见附件。第一行数据有9个空心圈,1个实心圈;第二行是10个数据。现在欲根据实心圈的位置,提取对应位置的第二行数据,用bat、vbs能够实现吗?
举例:
001.txt 文本内的数据为:
117 92--9023465718 ●○○○○○○○○○
           1397820564  
第一行10个圈,实心圈位于第一位,则提取第二行10个数据的第一位 1 ,写入C:/文本2/ 内的001.txt文本
若第一行10个圈实心圈位于第二位,则提取第二行10个数据的第二位 3 ,写入C:/文本2/ 内的001.txt文本
1

评分人数

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

本帖最后由 CrLf 于 2014-8-11 05:42 编辑

回复 15# xxpinqz


    提供一种用于此类特殊情况的长度算法:
  1. set "a=●○○○○○○○○○"
  2. set "b=%a:*●=%"
  3. set /a "len=0%b:○=+1%"
复制代码
----------------------------------------------------------------
还有求余的办法:
  1. set "a=●○○○○○○○○○"
  2. set "b=%a:*●=%"
  3. set /a "c=%b:○=1%,len=c/1000%%9+c%1000%%9"
复制代码
以前用 % 运算来改良生命游戏算法,和现在这个情况太相似了
----------------------------------------------------------------
还有一种思路也属于表驱动法,但用的是 for:
  1. set "a=●○○○○○○○○○"
  2. set "b=%a:*●=%"
  3. for /f "tokens=10" %%a in ("%b:○=. %9 8 7 6 5 4 3 2 1 0") do set "len=%%a"
复制代码

TOP

回复 15# xxpinqz
Len 的值可不用加 /a 效率提升
2

评分人数

TOP

本帖最后由 再世情緣 于 2014-8-4 01:56 编辑

回复 16# 思想之翼


    综合了之前那位朋友的方法,之后生成了目前的代码,但是,还是不可避免的要call一次。。。。
  1. @echo off &setlocal enabledelayedexpansion &color 0a
  2. set "var=%cd%"
  3. set "file1=文本"
  4. set "file2=文件夹"
  5. pushd %var% >nul
  6. for /l %%i in (1,1,9999) do (
  7.   if exist "!file1!%%i\*.txt" (
  8.    set "f1=!file1!%%i"
  9.    set "f2=!file2!%%i"
  10.     mkdir "!f2!" >nul 2>nul
  11.     call :head
  12.   )
  13. )
  14. pause.
  15. call exit
  16. :head
  17. for /f "delims=" %%a in ('dir /b /a -d /s "%f1%\*.txt" 2^>nul') do (
  18.   set "txtpath=%%~fa"
  19.   set "txtname=%%~nxa"
  20.   call :main !txtpath!
  21.   rem pause.>nul
  22. )
  23. rem pause.
  24. goto :eof
  25. :main
  26. for /f "usebackq tokens=3 delims= " %%a in ("%1") do (
  27.   set "code0=%%a" &&set "code0=!code0: =!"
  28.   set "code=!code0:*●=!" &&set "code=!code!#a9876543210"
  29.   for /f "usebackq skip=1" %%a in ("%1") do (
  30.     set "code2=%%a" &&set "code2=!code2: *=!"
  31.     set /a "len=0x!code:~10,1!","len0=11-len"
  32.     call :getnum
  33.   )
  34. )
  35. echo.当前处理文件:[!txtname!]
  36. echo.获取第一行有效字符:[!code0!]
  37. echo.获取第二行有效字符:[!code2!]
  38. echo.第一行 ● 所在位置:!len0!
  39. echo.第二行第 !len0! 个字符为: [!num!]
  40. echo.写入 [!num!] -^> "%cd%\!f2!\!txtname!"
  41. (echo.!num!)>"%cd%\!f2!\!txtname!"
  42. goto :eof
  43. :getnum
  44. set "num=!code2:~-%len%,1!"
  45. goto :eof
复制代码
1

评分人数

TOP

回复 15# xxpinqz

问题解决了,谢谢!

TOP

本帖最后由 xxpinqz 于 2014-8-4 01:44 编辑

回复 13# 再世情緣

拾人牙慧而已,这算法是大佬们写的。
http://www.bathome.net/thread-5861-1-1.html
http://www.bathome.net/viewthread.php?tid=11799&highlight=
大体这样会提升点效率:
  1. @echo off&setlocal enabledelayedexpansion
  2. cd /d "C:\文本1"
  3. for %%i in (*.txt) do (
  4.     for /f "tokens=*" %%a in (%%i) do (
  5.       if defined str (
  6.        set "num=%%~nxa"
  7.        for %%b in (!len!) do echo,!num:~-%%b,1!
  8.        set "str="
  9.       ) else (
  10.         set "str=%%~nxa#a9876543210"
  11.         set "str=!str:*●=!"
  12.         set /a len=0x!str:~10,1!
  13.       )  
  14.     )
  15. )>"C:\文件夹1\%%~nxi"
复制代码
1

评分人数

初学BAT,非专业。代码不适当之处还望前辈们多多指点。在此表示感谢!

TOP

回复 13# 再世情緣

再经过测试,代码出错了:改变110.txt  181.txt  190.txt  等文本的数据(格式不变),得到的结果依然是原先的数据。

TOP

回复 11# xxpinqz


    额。。。。佩服!!!你脑袋怎么长得。。。。怎么能想出来如此办法。。。

TOP

回复 10# 思想之翼


    。。。。你的意思是还有好多类似的文本1.....文件夹??

TOP

回复 7# 再世情緣

取位置不用那么麻烦,类似这样:
  1. @echo off&setlocal enabledelayedexpansion
  2. set "a=1397820564"
  3. set "b=117 92--9023465718 ●○○○○○○○○○#a9876543210"
  4. set "b=%b:*●=%"
  5. set /a len=0x%b:~10,1%
  6. echo,!a:~-%len%,1!
  7. pause
复制代码
初学BAT,非专业。代码不适当之处还望前辈们多多指点。在此表示感谢!

TOP

回复 9# 再世情緣

谢谢您给予的大力帮助,测试后解决问题。
但是产生了一个新问题:
需要提取“文本1”里的210个txt数据,写入“文件夹1”
需要提取“文本2”里的210个txt数据,写入“文件夹2”
需要提取“文本3”里的210个txt数据,写入“文件夹3”
...
您写的代码,修改哪里?

TOP

本帖最后由 再世情緣 于 2014-8-4 01:22 编辑

回复 8# 思想之翼


    额。。。。这是我自己测试的时候,为了查错,弄的,你把第十行
  1. pause.>nul
复制代码
删了就好了,或者改为
  1. rem pause.>nul
复制代码
注释掉也行

TOP

回复 7# 再世情緣

谢谢您的帮助!
经测试,只能自动提取001.txt,之后按一次回车键运行002.txt,再按回车键运行003.txt...要不停地按回车键

TOP

本帖最后由 再世情緣 于 2014-8-4 00:44 编辑
  1. @echo off &setlocal enabledelayedexpansion &color 0a
  2. set "var=%cd%"
  3. set "file=文件夹"
  4. pushd %var% >nul
  5. mkdir "%file%2" >nul 2>nul
  6. for /f "delims=" %%a in ('dir /b /a -d /s "%file%1\*.txt" 2^>nul') do (
  7.   set "txtpath=%%~fa"
  8.   set "txtname=%%~nxa"
  9.   call :main !txtpath!
  10.   pause.>nul
  11. )
  12. pause.
  13. call exit
  14. :main
  15. for /f "usebackq tokens=3 delims= " %%a in ("%1") do (
  16.   set "code0=%%a" &&set "code0=!code0: =!"
  17.   set "code=!code0:*●=!"
  18.   call :getlen
  19.   for /f "usebackq skip=1" %%a in ("%1") do (
  20.     set "code2=%%a" &&set "code2=!code2: *=!"
  21.     call :getnum
  22.   )
  23. )
  24. echo.当前处理文件:[!txtname!]
  25. echo.获取第一行有效字符:[!code0!]
  26. echo.获取第二行有效字符:[!code2!]
  27. echo.第一行 ● 所在位置:!len!
  28. echo.第二行第 !len! 个字符为: [!num!]
  29. echo.写入 [!num!] -^> "%cd%\!file!2\!txtname!"
  30. (echo.!num!)>"%cd%\!file!2\!txtname!"
  31. goto :eof
  32. :getlen
  33. if "!code!" EQU "" (
  34.   set /a "len=10"
  35.   goto :eof
  36. )
  37. set /a "i=0"
  38. :getlen_main
  39. set "code1=!code:~%i%,1!"
  40. if "!code1!" NEQ "" (
  41.   set /a "i+=1"
  42.   goto :getlen_main
  43. )
  44. set /a "len=10-i"
  45. goto :eof
  46. :getnum
  47. set /a "len0=len-1"
  48. set "num=!code2:~%len0%,1!"
  49. goto :eof
复制代码
说明:保存为bat之后,放在“文件夹1”同目录下,代码第三行
  1. set "file=文件夹"
复制代码
这里自定义你的文件夹的名字,不用带后面的数字,有问题回复我
代码中间
  1. echo.当前处理文件:[!txtname!]
  2. echo.获取第一行有效字符:[!code0!]
  3. echo.获取第二行有效字符:[!code2!]
  4. echo.第一行 ● 所在位置:!len!
  5. echo.第二行第 !len! 个字符为: [!num!]
  6. echo.写入 [!num!] -^> "%cd%\!file!2\!txtname!"
复制代码
部分为cmd窗口显示内容,可以删除,注意别把
  1. (echo.!num!)>"%cd%\!file!2\!txtname!"
复制代码
也删了。。。

代码可能会很繁琐。。。。
1

评分人数

TOP

回复 5# 思想之翼


    额。。。文件夹名字到底是“文件夹1” 还是 “文本1”。。。。

TOP

返回列表