[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖
&&看来此题对于普通会员来说具有一定的难度,下面给出本人的全解,并稍做说明,代码如下:
  1. @echo off&setlocal enabledelayedexpansion
  2. (for /f "delims=" %%a in ('findstr /r "<b>< <td.*d>$" a.txt') do (
  3.     set /a n+=1&if !n! equ 6 set /a n=1,m=0&echo.
  4.     if not defined m (
  5.        for /f "tokens=3,4 delims=/<>" %%b in ("%%a") do set /p=%%b <nul&if !n! equ 3 set /p=%%c <nul
  6.        ) else (
  7.        if !n! equ 1 for /f "tokens=4 delims=<>" %%b in ("%%a") do set /p=%%b <nul
  8.        if !n! equ 2 for /f "tokens=8 delims== " %%b in ("%%a") do set /p=http://bbs.bathome.net/%%~b <nul
  9.        if !n! equ 3 for /f "tokens=8,12,13 delims=<> " %%b in ("%%a") do set /p=%%b %%c-%%d <nul
  10.        if !n! equ 4 for /f "tokens=4,7 delims=<> " %%b in ("%%a") do set /p=%%b%%c <nul
  11.        if !n! equ 5 for /f "tokens=3 delims=<>" %%b in ("%%a") do set /p=%%b <nul
  12.     )
  13. ))>b.txt
  14. start b.txt
复制代码
说明:
    首先讲讲findstr正则的运用,大家都明白代码中运用findstr是为了最大限度地从a.txt中剔除无用信息行而提取有用信息行,所以

代码中使用了findstr /r "<b>< <td.*d>$" a.txt,之所以使用/r参数是为了让findstr识别后面的<td.*d>$表达式而不是全做为字符来处理

其中的$表示行尾,使用<b><的表达式的意思大家都知道我就不说明了,使用<td.*d>$表达式就可以提取所有含有<td字符并从中剔

除只以<td>结尾的行。

    接下来讲下代码中for /f "tokens=* delims=*"的运用,使用findstr正则提取了有用信息行后,接下来我们还要从每行中剔除无用

的信息,而保留输出想要的信息,一般来说可以采用两种办法,一种是字符截取,但因为文本中的字符数是在变化的,所以此法不

可用,那么我们就要利用好for /f中的tokens和delims参数了,先选取合适的足够的分隔符来将每行分成n列,注意在分隔时不要将

我们想要获取的字符部分分开了,同时尽量取特殊字符为分隔符而不要取常用的数字和字母,最后取我们所需要的列并输出就可以

了。

   看了13楼的长变量法(将每五行存入一个变量),我也尝试过用此法来解析出全信息,但实际上处理起来相当麻烦,希望有高人

能给出此法的精彩代码。
***共同提高***

TOP

学习了
  1. @echo off&setlocal enabledelayedexpansion
  2. set "s=http://bbs.bathome.net/"
  3. (for /f "tokens=3,4,5,7 delims=<>" %%a in ('findstr /r "<b>< <td.*d>$" a.txt') do (
  4.     set /a n+=1
  5.         if !n! gtr 5 (
  6.            if /i "%%c" equ "/a" (
  7.            if "%%d" neq "" (
  8.            for /f "tokens=1-3 delims== " %%i in ("%%d") do (
  9.               if "%%k" neq "" (set str=!str! %s%%%~k)else set "str=!str! %%b %%i-%%j"
  10.            )
  11.            ) else echo!str!&set "str= %%b"
  12.            ) else (
  13.              if /i "%%c" neq "" (
  14.              for %%i in (%%a) do set "str=!str! %%i%%c"
  15.             )else set str=!str! %%a
  16.            )
  17.          ) else for /f "tokens=1,2 delims=/" %%i in ("%%a") do (
  18.            if "%%j" equ "" (set str=!str! %%i)else set "str=!str! %%i %%j"
  19.          ))
  20.          echo!str!)>b.txt
  21. pause
复制代码
1

评分人数

    • batman: 拿分你最积极,另学习了PB + 30

TOP

  1. @echo off&setlocal enabledelayedexpansion
  2. for /f "tokens=1 delims=:" %%i in ('findstr /n """ratelogviewer""" a.txt') do set n=%%i
  3. set/an+=2
  4. for /f "skip=%n% tokens=2-3 delims=^<^>" %%i in (a.txt) do (
  5. if [%%j]==[] goto out
  6. set j=%%j
  7. set/p=!j:/= ! <nul
  8. )
  9. :out
  10. echo.
  11. set/an+=9
  12. for /f "eol=[ skip=%n% tokens=2-7 delims=^<^>" %%i in (a.txt) do (
  13. set/ai+=1
  14. if !i!==2 set/p=%%k <nul
  15. if !i!==4 set j=%%j&set j=!j:"=,!&for /f "tokens=2 delims=," %%z in ("!j!") do set/p=http://bbs.bathome.net/%%z<nul
  16. if !i!==7 set/p=%%k %%n <nul
  17. if !i!==8 set/p=%%j %%l <nul
  18. if !i!==9 set/p=%%j<nul
  19. if !i!==10 set i=0&pause
  20. )
复制代码
让我郁闷的代码

TOP

回复 18楼 的帖子

看了你的代码,我也着实郁闷,你处理得太复杂了吧,后面的结果根本不对。。。
***共同提高***

TOP

原帖由 batman 于 2009-12-12 17:35 发表
if !l! EQU 1 set/p=%%x%%y  


这个是去掉PB后面的空格.. 只不过都是输出到控制台,没>>B.TXT
本地运行正常啊...晕,昨天日期格式还正确的,今天就.... if 后也还得加个括号了

就是findstr /n 得到每个class=time(除了第一个time)的cow,然后for /f skip=cow 来取得后续几个元素
%l% 的值代表class=time 下面的第几行
因为 被评分者 看错成评分者了,所以 只取了2次就goto :eof
不过 帖子地址,被评分者 分别是%l%=5 ,6 时的行,稍扩展一下也能达到新的要求

[ 本帖最后由 caruko 于 2009-12-14 11:48 编辑 ]

TOP

回复 20楼 的帖子

像这种逐行(实际上不是每行)skip的方法,效率是最大的问题,如果有10000组数据要处理,那岂不是要用for

对文本读取10000次,还有被评者是在每组第一行的,请问用这种skip方法如何得到?就是经处理得到后,还不是

一样要处理滤过每组的第二行?再说了对空格的处理直接用delims不就行了,还要搞什么退格?
***共同提高***

TOP

回上..
效率确实不高 =.= 因为第2次读了文本
只不过对findstr不太熟,设计了几个复杂点的正则,结果都不对..

TOP

按效率, 代码简洁度, 格式适应度给出 3 个版本:

楼主的代码果然厉害, 又简短, 又高效, 学习!
对于 findstr, 尚在学习, 一开始思路也想到这个, 但终不熟悉于是换了方向
以下所有代码中 delims= 的后面直到 " 之间的若干空格其实都是一个 TAB 字符和一个半角空格, 复制代码请再替换一下, 看了 14 楼的提醒才知道论坛有这个问题
效率版(效率优先, 对 a.txt 文件格式变动适应差, 代码简洁度其次考虑)
  1. @echo off & setlocal enabledelayedexpansion
  2. for /f "eol=[ skip=69 delims=" %%a in (a.txt) do (
  3.   if "!doneHead!"=="" (
  4.         for /f "tokens=1-4 delims=></         " %%b in ("%%a") do (
  5.           if /i "%%c"=="class="time"" (set ln=!ln! %%d %%e) else (         
  6.             if "%%b"=="tbody" (echo !ln:~1!>b.txt)&(set doneHead=done)&(set lnBeratedOffs=-3) else (         
  7.                   if /i "%%b"=="td" set ln=!ln! %%c
  8.   ) ) ) ) else ( set /a "lnBeratedOffs+=1"
  9.     if !lnBeratedOffs! equ 0 (
  10.           for /f "tokens=1 delims=<>         " %%b in ("%%a") do if /i "%%b"=="/table" (
  11.             (start b.txt)&(if exist b样本.txt comp b样本.txt b.txt /l)& exit /b
  12.           ) else for /f "tokens=7 delims=&>?<         " %%z in ("%%a") do set ln=%%z
  13.         ) else if !lnBeratedOffs! equ 2 (
  14.           (set search=sTime)&(for /f "tokens=8 delims==         " %%b in ("%%a") do set ln=!ln! http://bbs.bathome.net/%%~b)
  15.         ) else if !lnBeratedOffs! geq 6 (
  16.           if "!search!"=="sTime" (  
  17.             for /f "tokens=2,6,10,11 delims=<>         " %%b in ("%%a") do (
  18.                   if /i "%%b"=="class="time"" (set ln=!ln! %%c %%d-%%e)&set search=bold)
  19.       ) else if "!search!"=="bold" (
  20.         (set search=cause)&(for /f "tokens=2,5 delims=<>         " %%b in ("%%a") do set ln=!ln! %%b%%c)
  21.           ) else if "!search!"=="cause" (
  22.             (set search=wait)&(set lnBeratedOffs=-3)&(for /f "tokens=2 delims=<>         " %%b in ("%%a") do echo !ln! %%b>>b.txt)
  23. ) ) ) )
复制代码
简洁版(以代码简洁优先, 效率及适应性考虑次之)
  1. @echo off & setlocal enabledelayedexpansion
  2. for /f "eol=[ skip=69 delims=" %%l in (a.txt) do (
  3.   if "!doneHead!"=="" (
  4.     for /f "tokens=1-4 delims=></         " %%A in ("%%l") do (
  5.       if /i "%%A"=="tbody" (set doneHead=done)&(echo !ln:~1!>b.txt) else (
  6.             if /i "%%B"=="class="time"" (set ln=!ln! %%C %%D) else if /i "%%A"=="td" (set ln=!ln! %%B)
  7.     ) )
  8.   ) else for /f "tokens=1-17 delims==&?></         " %%A in ("%%l") do (
  9.     if /i "%%A"=="tbody" (start b.txt)&(if exist b样本.txt comp b样本.txt b.txt /l)& exit /b
  10.     if /i "%%F"=="berated" (set ln=%%K http://bbs.bathome.net/)
  11.     if /i "%%K%%L"=="ahref" (set ln=!ln!%%~M) else if /i "%%L%%M"=="ahref" (set ln=!ln!%%~N)
  12.     if /i "%%C"==""time"" (set ln=!ln! %%M %%P-%%Q)
  13.     if /i "%%E"==""bold"" (set ln=!ln! %%B%%F)
  14.     if /i "%%C"=="td" echo !ln! %%B>>b.txt
  15. ) )
复制代码
适应版(起始不采用跳过指定行数, 而是根据搜索特定字符串找到记录表头, 适应 a.txt 文件格式变动略好)
  1. @echo off & setlocal enabledelayedexpansion
  2. for /f "eol=[ delims=" %%a in (a.txt) do (
  3.   if "!doneHead!"=="" (
  4.     for /f "tokens=2 delims=         " %%b in ("%%a") do if /i "%%b"=="summary="ratelogviewer"" (set doneHead=doing)
  5.   ) else if /i "!doneHead!"=="doing" (
  6.         for /f "tokens=1-4 delims=></         " %%b in ("%%a") do (
  7.           if /i "%%c"=="class="time"" (set ln=!ln! %%d %%e) else (
  8.             if "%%b"=="tbody" (echo !ln:~1!>b.txt)&(set doneHead=done)&(set lnBeratedOffs=-3) else (
  9.                   if /i "%%b"=="td" set ln=!ln! %%c
  10.     ) ) )
  11.   ) else ( set /a "lnBeratedOffs+=1"
  12.     if !lnBeratedOffs! equ 0 (
  13.           for /f "tokens=4,7 delims=&>?<         " %%b in ("%%a") do (set ln=%%c)
  14.         ) else if !lnBeratedOffs! equ 2 (
  15.           for /f "tokens=8 delims==         " %%b in ("%%a") do (set ln=!ln! http://bbs.bathome.net/%%~b)
  16.         ) else if !lnBeratedOffs! geq 6 (
  17.           for /f "tokens=1-6,10,11 delims=<>         " %%b in ("%%a") do (
  18.                 if /i "%%c"=="class="time"" (set ln=!ln! %%g %%h-%%i) else (
  19.                   if /i "%%e"=="class="bold"" (set ln=!ln! %%c%%f) else (
  20.                     if /i "%%d"=="/td" (echo !ln! %%c>>b.txt) else (
  21.                           if /i "%%b"=="tr" (set /a "lnBeratedOffs=-1") else if /i "%%b"=="/tbody" (
  22.                             (start b.txt)&(if exist b样本.txt comp b样本.txt b.txt /l)& exit /b
  23. ) ) ) ) ) ) ) )
复制代码

[ 本帖最后由 neorobin 于 2009-12-18 15:22 编辑 ]
1

评分人数

    • batman: 有参与就是好的PB + 30

TOP

回复 16楼 的帖子

不知楼主设想的变量法是怎样的
findstr + 大变量, 代码中的 ★ 代表 TAB 字符, 请复制后作相应替换
  1. @echo off&setlocal enabledelayedexpansion & cd.>b.txt & (set /a ii=-1)
  2. (for /f "delims=" %%a in ('findstr /r "<b>< <td.*d>$" a.txt') do (
  3.   (set ln=!ln!%%a)&(set /a "ii+=1,ii%%=5")
  4.   if not defined doneHead (
  5.         if !ii! equ 4 for /f "tokens=2,5,9,10,13,16 delims=></★ " %%A in ("!ln!") do (
  6.       set ln=%%A %%B %%C %%D %%E %%F)
  7.   ) else if !ii! equ 4 (
  8.     for /f "tokens=1,2,8,12-13,16,19,23 delims=<>★ " %%A in ("!ln!") do set ln=%%A %%B %%C %%D-%%E %%F%%G %%H
  9.   ) else ( if !ii! equ 1 for /f "tokens=9,23 delims==<>★ " %%A in ("!ln!") do (
  10.           set ln=%%A http://bbs.bathome.net/%%~B
  11.   ) )
  12.   if !ii! equ 4 (set /p=!ln!<nul& echo.)&(set doneHead=yes)&(set ln=)
  13. )>>b.txt) & (start b.txt)&(if exist b样本.txt comp b样本.txt b.txt /l)& exit /b
复制代码

[ 本帖最后由 neorobin 于 2009-12-18 20:46 编辑 ]

TOP

回复 24楼 的帖子

我所说的大变量法在前面16楼已经说明了,但要求比我16楼的代码还要简洁,目前苦无突破。。。
***共同提高***

TOP

回复 25楼 的帖子

这是结合13楼与16楼的特点的一个解法
将每五行文本连接拼成一个变量
为了规避for的32个tokens的限制
替换了空格、TAB和/A
为了解决双引号不能同时与其它字符做分隔符的问题
替换了双引号为单引号
  1. @echo off&setlocal enabledelayedexpansion
  2. (echo 被评分者 帖子内容预览 评分者 评分时间 积分变动 评分理由
  3. for /f "skip=5 delims=" %%i in ('findstr /r "pid= <td.*/td>$" a.txt') do (
  4. set /a n+=1
  5. set var=!var!%%i
  6. if !n!==5 (
  7. set foo=!var: =!
  8. set foo=!foo: =!
  9. set foo=!foo:"='!
  10. set foo=!foo:/a=!
  11. for /f "tokens=6,9,19,21,24,27,31 delims=<>'" %%a in ("!foo!") do (
  12. set url=http://bbs.bathome.net/%%b
  13. set ratetime=%%d
  14. echo.%%a !url:amp;=! %%c !ratetime:~0,-5!-!ratetime:~-5! %%e%%f %%g
  15. )
  16. set var=
  17. set n=0
  18. )
  19. ))>b.txt
  20. start b.txt
复制代码

[ 本帖最后由 qzwqzw 于 2011-3-13 19:53 编辑 ]
天的白色影子

TOP

你们不会善于使用 论坛 的功能 为关键代码着色
findstr 详细使用,书中有过记载的

TOP

返回列表