Board logo

标题: [文本处理] [分享]批处理查找连续三行包含指定关键字的行 [打印本页]

作者: Batcher    时间: 2023-3-7 12:20     标题: [分享]批处理查找连续三行包含指定关键字的行

【问题描述】

请问能批量统计文件中这样的相邻三行相同的特定的字母吗?
用findstr可以枚举出每一行,但要手工统计每个文件中出现的这个数量
这是文本内容,查找的是连续三行的“GGDEF”

作者: Batcher    时间: 2023-3-7 12:21

【解决方案】

test_1.bat
  1. @echo off
  2. cd /d "%~dp0"
  3. setlocal enabledelayedexpansion
  4. REM 待查找的文件名
  5. set "FileName=GCF_017498545.1_GGDEF2.out"
  6. REM 待查找的关键字
  7. set "KeyStr=GGDEF"
  8. for /f "tokens=1* delims=:" %%i in ('type "%FileName%" ^| findstr /n "%KeyStr%"') do (
  9.     set "ColumnA0=!ColumnA1!"
  10.     set "ColumnA1=!ColumnA2!"
  11.     set "ColumnA2=%%i"
  12.     set "ColumnB0=!ColumnB1!"
  13.     set "ColumnB1=!ColumnB2!"
  14.     set "ColumnB2=%%j"
  15.     set /a MinusNum1=ColumnA1-ColumnA0
  16.     set /a MinusNum2=ColumnA2-ColumnA1
  17.     if !MinusNum1! equ 1 (
  18.         if !MinusNum2! equ 1 (
  19.             REM 显示效果是 行号:文本内容
  20.             echo !ColumnA0!:!ColumnB0!
  21.             echo !ColumnA1!:!ColumnB1!
  22.             echo !ColumnA2!:!ColumnB2!
  23.         )
  24.     )
  25. )
  26. pause
复制代码

作者: 帝尊    时间: 2023-3-7 12:40

  1. @echo off
  2. setlocal enabledelayedexpansion
  3. set "search=GGDEF"
  4. set count=0
  5. for /f "delims=" %%a in ('findstr /n /c:"%search%" input.txt') do (
  6.     set /a line=%%a
  7.     set /a prev=!line!-1
  8.     set /a next=!line!+1
  9.     findstr /n "^" input.txt | findstr /b "!prev!: !next!: !line!:"
  10.     if !errorlevel!==0 (
  11.         set /a count+=1
  12.     )
  13. )
  14. echo Count: %count%
复制代码
不知道行不行
作者: Batcher    时间: 2023-3-7 14:33

回复 3# 帝尊


求助者给出的真实文本里面,有的行包含关键字,有的行不包含关键字;
有的行包含关键字,但是不满足连续三行都包含关键字。
作者: qixiaobin0715    时间: 2023-3-7 16:26

实际上求助者的问题不是太严密。
最多有连续3行包含关键字应当问题不大,如果有连续4行、5行、6行...包含关键字,求助者未明确如何处理:
1.如果无论如何,只要有连续3行包含关键字都显示,即使重叠也没关系,可以使用Batcher提供的代码;
2.如果不能重叠,比如1~5行都含有关键字,只取1~3行,Batcher的代码这样修改;
  1. @echo off
  2. cd /d "%~dp0"
  3. setlocal enabledelayedexpansion
  4. REM 待查找的文件名
  5. set "FileName=1.txt"
  6. REM 待查找的关键字
  7. set "KeyStr=GGDEF"
  8. for /f "tokens=1* delims=:" %%i in ('type "%FileName%" ^| findstr /n "%KeyStr%"') do (
  9.     set "ColumnA0=!ColumnA1!"
  10.     set "ColumnA1=!ColumnA2!"
  11.     set "ColumnA2=%%i"
  12.     set "ColumnB0=!ColumnB1!"
  13.     set "ColumnB1=!ColumnB2!"
  14.     set "ColumnB2=%%j"
  15.     set /a MinusNum1=ColumnA1-ColumnA0
  16.     set /a MinusNum2=ColumnA2-ColumnA1
  17.     if !MinusNum1! equ 1 (
  18.         if !MinusNum2! equ 1 (
  19.             REM 显示效果是 行号:文本内容
  20.             echo !ColumnA0!:!ColumnB0!
  21.             echo !ColumnA1!:!ColumnB1!
  22.             echo !ColumnA2!:!ColumnB2!
  23.             set ColumnA2=
  24.         )
  25.     )
  26. )
  27. pause
复制代码
3.如果第2条的情况中,1~5行都显示,Batcher的代码这样修改;
  1. @echo off
  2. cd /d "%~dp0"
  3. setlocal enabledelayedexpansion
  4. REM 待查找的文件名
  5. set "FileName=1.txt"
  6. REM 待查找的关键字
  7. set "KeyStr=GGDEF"
  8. for /f "tokens=1* delims=:" %%i in ('type "%FileName%" ^| findstr /n "%KeyStr%"') do (
  9.     set "ColumnA0=!ColumnA1!"
  10.     set "ColumnA1=!ColumnA2!"
  11.     set "ColumnA2=%%i"
  12.     set "ColumnB0=!ColumnB1!"
  13.     set "ColumnB1=!ColumnB2!"
  14.     set "ColumnB2=%%j"
  15.     set /a MinusNum=ColumnA2-ColumnA1
  16.     if !MinusNum! equ 1 (
  17.         set /a n+=1
  18.         if !n! equ 2 (
  19.             REM 显示效果是 行号:文本内容
  20.             echo !ColumnA0!:!ColumnB0!
  21.             echo !ColumnA1!:!ColumnB1!
  22.             echo !ColumnA2!:!ColumnB2!
  23.         ) else if !n! gtr 2 echo,!ColumnA2!:!ColumnB2!
  24.     ) else set n=0
  25. )
  26. pause
复制代码

作者: Batcher    时间: 2023-3-7 16:45

回复 5# qixiaobin0715


虽然提问者没有明说,不过据我观察真实文本里面的规律大概是:
Query开头的行,包含关键字
中间一行,包含关键字
Sbjct开头的行,包含关键字

这样的三行为一组,提取出来。暂时没发现特殊情况。
作者: qixiaobin0715    时间: 2023-3-7 16:51

原来如此,想复杂了。
作者: aloha20200628    时间: 2023-3-7 20:29

给出另一个算法》查找文件中连续出现n(>=3)次关键词的行序号
  1. @echo off
  2. set "inF=gg.out" &set "ks=GGDEF" &set "xL=-2"
  3. setlocal enabledelayedexpansion
  4. for /f "tokens=1 delims=:" %%x in ('findstr /nc:"%ks%" "%inF%" ') do (
  5.   set /a "dx=%%x-!xL!"
  6.   if !dx! equ 1 (set "a=!a!,%%x") else (
  7.       set "n=0" &for %%n in (!a!) do (set /a n+=1)
  8.       if !n! geq 3 echo,!a!
  9.       set "a=%%x"
  10.   )
  11.   set "xL=%%x"
  12. )
  13. set "n=0" &for %%n in (!a!) do (set /a n+=1)
  14. if !n! geq 3 echo,!a!
  15. endlocal &pause &exit/b
复制代码





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