Board logo

标题: [文本处理] [已解决]求助批处理怎样取多个同一关键词行的下一行 [打印本页]

作者: hlzj88    时间: 2022-10-22 13:55     标题: [已解决]求助批处理怎样取多个同一关键词行的下一行

某崖的小说遇到值的读的,想提取到一文本集中阅读楼主。
多个网页下载合并后,已提取到源码内容为   发言人  下一行为发言内容。由于网友回贴,造成如下示例的内容间杂。所以还需要提取楼主的发言并其他加工。格式大致如下

<divclass="atl-info"><span>楼主:<ahref="http://www
<divclass="bbs-contentclearfix">  爷爷是传承五代人的  这行留
<divclass="atl-info"><span><strongclass="host">楼主</strong>:<ahref="http://www
<divclass="bbs-content">  床尾站着一小仙,男,中批  这行留
<divclass="atl-info"><span><strongclass="host">其他发言人</strong>
<divclass="bbs-content">  其他发言人的发言,特点长短不一,也可能引用楼主大段文字
<divclass="atl-info"><span><strongclass="host">楼主</strong>:<ahref="http://www
<divclass="bbs-content"><br>  <imgsrc="http://static.tianyaui.com/img/static/2011/imgloading.gif"title="点击图片  这行留
<divclass="atl-info"><span><strongclass="host">楼主</strong>:<ahref="http://www
<divclass="bbs-content">  那日入定,爷爷带  这行留
  1. @echo on&&setlocal enabledelayedexpansion
  2. for /f "tokens=1 delims=:" %%i in ('findstr /n "楼主" 33.txt') do (
  3.   echo 楼主标志的行号 %%i
  4.   set /a xy=%%i+1
  5.   set js=
  6. for /f "delims=" %%m in ("33.txt") do (
  7.   set /a js+=1
  8.   if !xy!==!js! echo %%m>>44.txt
  9.   echo 标准!xy!  计数!js!
  10. )
  11. )
  12. pause
复制代码
我尝试写的代码,计数!js!永远为 1,因此提不到楼主发言。所以求助,感谢给予帮助。     结贴时对上面略改
作者: pd1    时间: 2022-10-22 15:06

上面这段文本最后提取出来的是什么样的?
作者: hlzj88    时间: 2022-10-22 15:26

回复 2# pd1
要2  4  8  10行,即有楼主的下一行。
作者: pd1    时间: 2022-10-22 15:30

回复 3# hlzj88


    我意思就谁要行号还是内容,要内容的话<divclass="bbs-contentclearfix">   <divclass="bbs-conte   这些内容全部都留着?
作者: hfxiang    时间: 2022-10-22 15:33

如不介意第3方工具gawk( http://bcn.bathome.net/tool/4.1.0/gawk.exe ),假设下载合并后的文件为“1.txt”,则以下代码可实现
  1. gawk "{if(A)if(B!=$0)if(NF){$0=gensub(/<.*>[ \t]*/,\"\",\"g\");print};A=0}/^楼主/{A=1;B=$0}" 1.txt>2.txt
复制代码

作者: pd1    时间: 2022-10-22 15:35

本帖最后由 pd1 于 2022-10-22 15:36 编辑

上面是行号,下面的是内容
  1. <# :
  2. @echo off
  3. powershell -NoProfile -ExecutionPolicy bypass "Get-Content -literal '%~f0' |Out-String|Invoke-Expression"
  4. pause
  5. #>
  6. $a=gc .\333.txt
  7. 0..($a.Length-1) |%{if($a[$_].contains(">楼主")){$_+2}}
复制代码
  1. <# :
  2. @echo off
  3. powershell -NoProfile -ExecutionPolicy bypass "Get-Content -literal '%~f0' |Out-String|Invoke-Expression"
  4. pause
  5. #>
  6. $a=gc .\333.txt
  7. 0..($a.Length-1) |%{if($a[$_].contains(">楼主")){$a[$_+1]}}
复制代码

作者: pd1    时间: 2022-10-22 15:37

http://www.bathome.net/viewthread.php?from=notice&tid=64034
和你的需求一样的帖子
作者: fzp070    时间: 2022-10-22 15:47

回复 3# hlzj88


    如下代码,可以达到楼主你的要求,在55.txt内,文字前面内容未去除
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. for /f "tokens=1 delims=" %%k in ('findstr /n .* 33.txt')do (echo %%k>>44.txt)
  4. for /f "delims=:" %%i in ('findstr /n .">楼主" 33.txt') do (
  5.   echo 楼主标志的行号 %%i
  6.   set /a xy=%%i+1
  7. for /f "tokens=1* delims=:" %%m in ('findstr .* 44.txt')do (
  8. set tt=%%m
  9. if !xy!==!tt! echo %%n>>55.txt
  10. )
  11. )
  12. del /f/q 44.txt
  13. pause
复制代码
最终结果(55.txt内容):
  1. <divclass="bbs-contentclearfix">  爷爷是传承五代人的
  2. <divclass="bbs-content">  床尾站着一小仙,男,中批
  3. <divclass="bbs-content"><br>  <imgsrc="http://static.tianyaui.com/img/static/2011/imgloading.gif"title="点击图片
  4. <divclass="bbs-content">  那日入定,爷爷带
复制代码

作者: fzp070    时间: 2022-10-22 16:09

回复 3# hlzj88


   补充去除文字外的字符:
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. for /f "tokens=1 delims=" %%k in ('findstr /n .* 33.txt')do (echo %%k>>44.txt)
  4. for /f "delims=:" %%i in ('findstr /n .">楼主" 33.txt') do (
  5.   echo 楼主标志的行号 %%i
  6.   set /a xy=%%i+1
  7. for /f "tokens=1* delims=:" %%m in ('findstr .* 44.txt')do (
  8. set tt=%%m
  9. if !xy!==!tt! echo %%n>>55.txt
  10. )
  11. )
  12. del /f/q 44.txt
  13. for /f "tokens=1* delims=>  " %%a in ('findstr .* 55.txt')do (
  14. echo %%b>>66.txt
  15. )
  16. pause
复制代码
最终结果(66.txt内容):
  1. 爷爷是传承五代人的
  2. 床尾站着一小仙,男,中批
  3. <br>  <imgsrc="http://static.tianyaui.com/img/static/2011/imgloading.gif"title="点击图片
  4. 那日入定,爷爷带
复制代码

作者: hlzj88    时间: 2022-10-22 16:12

谢谢楼上的各位,是要那些行的所有内容。
作者: fzp070    时间: 2022-10-22 16:15

回复 10# hlzj88


    那8楼符合,你试试
作者: hfxiang    时间: 2022-10-22 16:22

回复 10# hlzj88


   
如果所有信息都保留,5楼的可简化为
  1. gawk "A;A=0;/^楼主/{A=1}" 1.txt>2.txt
复制代码

作者: fzp070    时间: 2022-10-22 17:00

回复 12# hfxiang


    好精简,不过我刚特意下载试了下,生成的2.txt/3.txt文件内为空且会变成UTF-8格式。是不是代码运用错了?
  1. @echo off
  2. gawk "{if(A)if(B!=$0)if(NF){$0=gensub(/<.*>[ \t]*/,\"\",\"g\");print};A=0}/^楼主/{A=1;B=$0}" 33.txt>2.txt
  3. pause
  4. gawk "A;A=0;/^楼主/{A=1}" 33.txt>3.txt
  5. pause
复制代码

作者: hfxiang    时间: 2022-10-22 17:20

回复 13# fzp070


   
脚本及代处理文件(如你的“33.txt”)均需确保为ANSI编码格式方可
作者: fzp070    时间: 2022-10-22 17:24

回复 14# hfxiang


   文本和批处理,都是ANSI格式的,而且我提前准备了ANSI格式的2.txt和3.txt,待批处理运行后,就变成空的了,而且格式自动转为UTF-8了,你可以亲自试试。谢谢!
作者: hfxiang    时间: 2022-10-22 17:30

回复 15# fzp070


俺反复测试完全正常,结果如下:
  1. D:\test>gawk "{if(A)if(B!=$0)if(NF){$0=gensub(/<.*>[ \t]*/,\"\",\"g\");print};A=0}/^楼主/{A=1;B=$0}" 1.txt
  2. 爷爷是传承五代人的
  3. 床尾站着一小仙,男,中批
  4. 那日入定,爷爷带
  5. D:\test>gawk "A;A=0;/^楼主/{A=1}" 1.txt
  6. <divclass="bbs-contentclearfix">  爷爷是传承五代人的
  7. <divclass="bbs-content">  床尾站着一小仙,男,中批
  8. <divclass="bbs-content">  那日入定,爷爷带
复制代码

作者: fzp070    时间: 2022-10-22 17:36

回复 6# pd1

试了下,好像有问题啊,是哪里原因?错误信息见下。
批处理当前目录有 333.txt文档,报错后在目录C:\Windows\System32\WindowsPowerShell\v1.0\放入333.txt文档仍会如下报错:
  1. gc : 找不到路径“C:\Windows\System32\WindowsPowerShell\v1.0\333.txt”,因为该路径不存在。
  2. 所在位置 行:6 字符: 4
  3. + $a=gc .\333.txt
  4. +    ~~~~~~~~~~~~
  5.     + CategoryInfo          : ObjectNotFound: (C:\Windows\Syst...ll\v1.0\333.txt:String) [Get-Content], ItemNotFoundEx
  6.    ception
  7.     + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetContentCommand
  8. 无法对 Null 数组进行索引。
  9. 所在位置 行:7 字符: 24
  10. + 0..($a.Length-1) |%{if($a[$_].contains(">楼主")){$_+2}}
  11. +                        ~~~~~~~~~~~~~~~~~~~~~~
  12.     + CategoryInfo          : InvalidOperation: (:) [],RuntimeException
  13.     + FullyQualifiedErrorId : NullArray
  14. 无法对 Null 数组进行索引。
  15. 所在位置 行:7 字符: 24
  16. + 0..($a.Length-1) |%{if($a[$_].contains(">楼主")){$_+2}}
  17. +                        ~~~~~~~~~~~~~~~~~~~~~~
  18.     + CategoryInfo          : InvalidOperation: (:) [],RuntimeException
  19.     + FullyQualifiedErrorId : NullArray
  20. 请按任意键继续. . .
复制代码

作者: fzp070    时间: 2022-10-22 17:44

回复 16# hfxiang


    是系统原因吗?我的是Win11系统。
附验证动图 https://wwp.lanzouv.com/izR2l0ednn2b
作者: hfxiang    时间: 2022-10-22 17:52

回复 18# fzp070


   
俺的电脑太老旧了(2011年买的),目录已用Win10了(已经很卡顿了),win11从没想过尝试安装,有可能是系统问题,但具体原因真不清楚
作者: fzp070    时间: 2022-10-22 17:53

回复 19# hfxiang


    好的,谢谢了
作者: hlzj88    时间: 2022-10-22 19:20

回复 11# fzp070
谢谢,因为实际情况比1楼描述的还复杂一些,保留是可以观察。如果后面我这里整体调试好了,倒是可以参考使用的。
作者: hlzj88    时间: 2022-10-22 19:27

回复 19# hfxiang
我的电脑应该比你的还早一些。一直使用win7。试了powershell都不能运行。当然我比电脑大很多,所以学技术上很大难度。光一连串的字母,念不了也写不出。因此局限很大。只能在批处理这样简单字母上下下功夫。
作者: hlzj88    时间: 2022-10-22 19:34

回复 12# hfxiang
谢谢,一直去调试文章了,我试了两个版本的gawk,都是空白的,没有变utf-8。win7 32位
作者: pd1    时间: 2022-10-22 19:51

回复 17# fzp070


    放在bat目录,不用放c盘,ANSI格式
作者: fzp070    时间: 2022-10-22 20:25

回复 24# pd1


   是放在bat目录,是 ANSI格式,就是不行啊。可能也是系统差异。
作者: WHY    时间: 2022-10-22 20:34

本帖最后由 WHY 于 2022-10-23 11:23 编辑
  1. sed -r -n "/>楼主:?</{n;p}" a.txt > b.txt
复制代码
  1. gawk "a~/>楼主:?</{print};{a=$0}" a.txt > b.txt
复制代码
  1. PowerShell "sc -Literal '%~dp0b.txt' $(forEach( $s In (gc -Literal '%~dp0a.txt' -Read 0) ){ if($a -match '>楼主:?<'){$s} $a=$s })"
复制代码
  1. PowerShell "gc -Literal '%~dp0a.txt' | Select-String '>楼主:?<' -Context 1 | forEach{ $_.Context.PostContext } | sc -Literal '%~dp0b.txt'"
复制代码

作者: fzp070    时间: 2022-10-22 20:42

回复 26# WHY


    厉害!4个命令中,除了第一个生成空白,其它三个都有效。
作者: hlzj88    时间: 2022-10-22 20:56

回复  WHY


    厉害!4个命令中,除了第一个生成空白,其它三个都有效。
fzp070 发表于 2022-10-22 20:42


同样,gawk秒好

感谢!
作者: WHY    时间: 2022-10-22 20:59

回复 27# fzp070


    http://bcn.bathome.net/tool/4.4/sed.exe
我用的这个版本
作者: WHY    时间: 2022-10-22 21:01

  1. @echo off
  2. setlocal enabledelayedexpansion
  3. for /f "delims=" %%i in (a.txt) do (
  4.     if defined s (
  5.         if "!s:>楼主=!" NEQ "!s!" (
  6.             echo;%%i
  7.         )
  8.     )
  9.     set "s=%%i"
  10. )
  11. pause
复制代码

作者: fzp070    时间: 2022-10-22 21:04

回复 29# WHY


    感谢!你的这个sed.exe可以。
我下载了几个sed.exe,还下了对应dll试了都不行。还是你得好。
作者: fzp070    时间: 2022-10-22 21:10

回复 30# WHY

  已试有效,代码很精简,学习了!
作者: hlzj88    时间: 2022-10-22 21:17

我的也是,不是我常用的sed版本。
作者: terse    时间: 2022-10-22 23:51

本帖最后由 terse 于 2022-10-23 00:36 编辑
  1. powershell "(select-string 'a.txt' -pattern '>楼主:?<' –context 1).Context.PostContext" >a11.txt
复制代码
处理ANSl编码
  1. powershell "(select-string 'a.txt' -pattern '>楼主:?<' –context 1  -Encoding default ).Context.PostContext" >a_#.txt
复制代码

作者: fzp070    时间: 2022-10-23 00:21

回复 34# terse

在我电脑系统上运行报错:
  1. select-string : 找不到路径“C:\Windows\System32\WindowsPowerShell\v1.0\a.txt”,因为该路径不存在。
  2. 所在位置 行:1 字符: 2
  3. + (select-string 'a.txt' -pattern '>楼主:?<' –context 1).Context.PostCont ...
  4. +  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  5.     + CategoryInfo          : ObjectNotFound: (C:\Windows\Syst...hell\v1.0\a.txt:String) [Select-String], ItemNotFound
  6.    Exception
  7.     + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.SelectStringCommand
复制代码

作者: terse    时间: 2022-10-23 00:38

回复 35# fzp070

找不到文件? 没有A.txt吗?
作者: fzp070    时间: 2022-10-23 00:45

回复 36# terse


    在批处理所在目录 和如下目录 均放有A.txt,但跟6楼的powershell命令情况一样,在我电脑都提示找不到文本。目前只有26楼的 两个powershell命令 在我的电脑均正常
  1. “C:\Windows\System32\WindowsPowerShell\v1.0\a.txt”
复制代码

作者: fzp070    时间: 2022-10-23 01:05

回复 34# terse
  1. powershell "(select-string 'a.txt' -pattern '>楼主:?<' –context 1).Context.PostContext" >a11.txt
  2. powershell "(select-string 'a.txt' -pattern '>楼主:?<' –context 1  -Encoding default ).Context.PostContext" >a_#.txt
复制代码
    大概找到原因了,跟目录名称是否含有特殊字符有关
例如目录是E:\11\,你34楼的两条命令都不报错,但第1条命令输出为空,第2条命令正常
如果目录是E:\[文本处理] 提文求助:取\,则两条命令都报错,找不到文本
也就是说34楼两条命令没有对含有特殊字符的目录进行处理。
作者: terse    时间: 2022-10-23 20:16

回复 38# fzp070
如有特殊字符 加个参数试下 类似于这样
  1. select-string -Lit 'e:\[文本处理] 提文求助:取\a1.txt'   ......  
复制代码

作者: fzp070    时间: 2022-10-23 21:58

回复 39# terse


    嗯,这样之后,第2条命令正常了(第1条不报错,但输出空白),但也不方便了,每次使用都要手动输入目录,目录太长还不好看。
作者: terse    时间: 2022-10-23 22:29

回复 40# fzp070
简单事给复杂化了,两条用上一条就可以了,文件编码是UTF-8的话就用第一条命令,编码ANSL就用第二条命令,脚本和文件同一目录处理
  1. powershell "(select-string  -Lit '%~dp0a.txt' -pattern '>楼主:?<' –context 1 ).Context.PostContext" >a_a.txt
复制代码
  1. powershell "(select-string -Lit '%~dp0a1.txt' -pattern '>楼主:?<' –context 1 -Encoding default).Context.PostContext" >a_1.txt
复制代码

作者: fzp070    时间: 2022-10-23 22:58

回复 41# terse


    OK,这次两条都可以了。谢谢分享!
作者: qixiaobin0715    时间: 2022-10-24 10:10

纯p 处理文本文件不是强项,下面代码勉强可用,效率应当不是太好。bat文件保存为ANSI编码,要处理的文本最好也是ANSI编码:
  1. @echo off
  2. set n=0
  3. setlocal enabledelayedexpansion
  4. (for /f "delims=" %%i in (33.txt) do (
  5.     if !n! equ 1 echo,%%i
  6.     set "str=%%i"
  7.     if not "!str:>楼主=!"=="!str!" (set n=1) else set n=0
  8. ))>44.txt
  9. pause
复制代码

作者: hlzj88    时间: 2022-10-24 12:36

回复 43# qixiaobin0715
速度也不慢,1M文本处理也是瞬间的事
作者: WHY    时间: 2022-10-24 19:27

贴一个 grep 方案,没有 gawk 和 sed 来的方便。
  1. grep -P -A1 --no-group-separator ">楼主(:)?<" a.txt | grep -P -v ">楼主(:)?<" | find /v "" > b.txt
复制代码

作者: WHY    时间: 2022-10-24 19:38

Win7 默认的 PowerShell v2.0 中的 Select-String 不支持 -LiteralPath 参数
PowerShell "..." > b.txt 这种重定向方式也有问题,字符串会自动断行。
这样测试:PowerShell -v 2.0 "..." > b.txt
作者: hlzj88    时间: 2022-10-24 20:24

回复 46# WHY
的确出现了自动断行的情况,不过由于是直接提取网页源码,最后以htox32c网页转文本的方式,没有什么影响。同时,图文混合的源码,图片也自动没有了。
作者: aloha20200628    时间: 2022-10-25 16:56

长贴凑趣》据LZ三楼回复之意,顺借本题复习一下纯P伪数组的用法...
  1. @echo off
  2. for %%n in (2,4,8,10) do set "[%%n]=%%n" &::建立伪数组 [n]=n 对应行序号
  3. set "n=0" &setlocal enabledelayedexpansion
  4. (for /f "delims=" %%s in (33.txt) do (
  5. set/a "n+=1" &for %%k in (!n!) do set "An=![%%k]!"
  6. if !An! equ !n! echo,%%s
  7. ))>44.txt
复制代码





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