【问题标题】:Find and extract text from within existing text file从现有文本文件中查找和提取文本
【发布时间】:2012-02-12 14:18:35
【问题描述】:

我需要能够从现有文本文件中提取数据。文本文件的结构看起来像这样......

this line contains a type of header and always starts at column 1
     this line contains other data and is always tabbed in
     this line contains other data and is always tabbed in
     this line contains other data and is always tabbed in
     this line contains other data and is always tabbed in
     this line contains other data and is always tabbed in
     this line contains other data and is always tabbed in

this line contains a type of header and always starts at column 1
     this line contains other data and is always tabbed in
     this line contains other data and is always tabbed in
     this line contains other data and is always tabbed in

this line contains a type of header and always starts at column 1
     this line contains other data and is always tabbed in
     this line contains other data and is always tabbed in
     this line contains other data and is always tabbed in
     this line contains other data and is always tabbed in

this line contains a type of header and always starts at column 1
     this line contains other data and is always tabbed in
     this line contains other data and is always tabbed in

如您所见,文本文件按部分排列。总是有一个标题行,后面跟着随机数量的其他数据行,节之间总是有一个空行。不幸的是,标题部分的命名方案或其他数据行中包含的数据没有押韵或理由......只有上述结构有点一致。我需要搜索的数据位于其他数据行之一中,仅位于其中一个部分中,该部分可能位于文本文件中的任何位置。我可以使用 FIND 命令来定位我需要查找的文本,但是一旦我这样做了,我需要能够将整个部分提取到一个新的文本文件中。我不知道如何在前面的第一个空白行上增加多少行,然后向下到下一个空白行,并提取其间的所有内容。那有意义吗?不幸的是,VBScript 根本不是这个应用程序的一个选项,否则它早就结束了。有任何想法吗?谢谢。

【问题讨论】:

    标签: batch-file extract text-files


    【解决方案1】:
    @echo off
    setlocal enableDelayedExpansion
    set input="test.txt"
    set output="extract.txt"
    set search="MY TEXT"
    
    ::find the line with the text
    for /f "delims=:" %%N in ('findstr /n /c:!search! %input%') do set lineNum=%%N
    set "begin=0"
    
    ::find blank lines and set begin to the last blank before text and end to the first blank after text
    for /f "delims=:" %%N in ('findstr /n "^$" %input%') do (
      if %%N lss !lineNum! (set "begin=%%N") else set "end=%%N" & goto :break
    )
    ::end of section not found so we must count the number of lines in the file
    for /f %%N in ('find /c /v "" ^<%input%') do set /a end=%%N+1
    :break
    
    ::extract the section bracketed by begin and end
    set /a count=end-begin-1
    <%input% (
      rem ::throw away the beginning lines until we reach the desired section
      for /l %%N in (1 1 %begin%) do set /p "ln="
        rem ::read and write the section
        for /l %%N in (1 1 %count%) do (
          set "ln="
          set /p "ln="
          echo(!ln!
        )
    )>%output%
    

    此解决方案的限制:

    • 行必须以&lt;CR&gt;&lt;LF&gt; 终止(Windows 样式)
    • 行的长度必须 <CR><LF>)
    • 将从每一行中去除尾随控制字符

    如果限制是一个问题,那么可以编写一个效率较低的变体,使用 FOR /F 而不是 SET /P 读取该部分

    【讨论】:

    • @StevenSinclair - 如果可行,请不要忘记单击复选标记以将其选为解决方案。如果您认为这个答案有用,那么您也可以投票给答案(如果您愿意的话)。
    【解决方案2】:

    下面的程序读取文件行并将一节的行存储在向量中,同时检查搜索文本是否在当前节内。当节结束时,如果找到了搜索文本,则输出当前节作为结果;否则,流程转到下一部分。

    @echo off
    setlocal EnableDelayedExpansion
    set infile=input.txt
    set outfile=output.txt
    set "search=Any text"
    set textFound=
    call :SearchSection < %infile% > %outfile%
    goto :EOF
    
    :SearchSection
       set i=0
       :readNextLine
          set line=
          set /P line=
          if not defined line goto endSection
          set /A i+=1
          set "ln%i%=!line!"
          if not "!ln%i%!" == "!line:%search%=!" set textFound=True
       goto readNextLine
       :endSection
       if %i% == 0 echo Error: Search text not found & exit /B
    if not defined textFound goto SearchSection
    for /L %%i in (1,1,%i%) do echo !ln%%i!
    exit /B
    

    这个程序的局限性与 dbenham 为他的程序所说的一样。

    【讨论】:

    • 优雅的解决方案,虽然我怀疑 GOTO 循环会使它比我的解决方案慢,尤其是在大文件末尾找到文本时。我没有测试过。
    • @dbenham: 我的方法会运行得更快一些WHILE macros 而不是 GOTO 的,比如::SearchSection%WHILE% not defined textfound DO (%WHILE% not defined textfound DO (set i=0set line=set /P line=%WHILE% defined line DO ( 等...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-18
    • 1970-01-01
    • 1970-01-01
    • 2017-10-05
    • 2014-05-18
    • 1970-01-01
    相关资源
    最近更新 更多