2012-01-17 17 views
1

既存のテキストファイルからデータを抽出できる必要があります。テキストファイルの構造は次のようになります。既存のテキストファイル内のテキストを検索して抽出する

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 

ご覧のとおり、テキストファイルはセクションごとに配置されています。常に1つのヘッダー行が続き、ランダムな数の他のデータ行が続き、セクション間には常に空白行があります。残念ながら、ヘッダーセクションの命名方式や他のデータラインに含まれるデータには韻や理由がありません。上記の構造だけがやや一貫しています。私が検索する必要のあるデータは、テキストファイル内のどこにでも置くことができるセクションのうちの1つのみの、他のデータラインの1つに配置されています。私はFINDコマンドを使って見つける必要があるテキストを見つけることができますが、一度それを行うと、セクション全体を新しいテキストファイルに抽出できるようにする必要があります。私はどのように最初の空白行に最初の行に多くの行を上がって、次に次の空白行に移動し、間にすべてを抽出する方法を把握することはできません。それは理にかなっていますか?残念ながら、VBScriptは単にこのアプリケーションのオプションではありません。あるいは、ずっと前から終了してしまっていたでしょう。何か案は? 〜この解決のための

答えて

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% 

制限事項:

  • 行は
  • 行は制御文字
  • <CR><LF>は含まない)末尾< = 1021バイト長でなければなりません<CR><LF>(Windowsスタイル)で終了する必要があります 各行から削除されます。

制限が問題の場合は、SET/Pの代わりにFOR/Fを使用してセクションを読み取る効率の悪いバリアントを書き込むことができます。

+0

これは完璧に機能しました!ありがとうございました!!! –

+0

@StevenSinclair - これがうまくいく場合、チェックマークをクリックしてソリューションとして選択することを忘れないでください。この答えが役に立つと思うなら、あなたは答えを投票することもできます。 – dbenham

1

以下のプログラムはファイル行を読み取り、1つのセクションの行をベクトル検索テキストが現在のセクションの中にあるかどうかをチェックするのと同じ時間。セクションが終了すると、検索されたテキストが見つかった場合、現在のセクションが結果として出力されます。それ以外の場合、プロセスは次のセクションに進みます。

@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が彼のプログラムについて述べた制限と同じです。

+0

GOTOループが私の解決策よりも遅くなると思われますが、特に大きなファイルの最後にテキストが見つかった場合は、優雅な解決策です。私はテストしていない。 – dbenham

+0

@dbenham:私の方法はGOTOの代わりにいくつかの[WHILE macros](http://www.dostips.com/forum/viewtopic.php?f=3&t=2707&p=12415#p12415)を使ってもっと速く動作します。 '' set i = 0'' set line = '' set/P '' = ''%WHILE%定義された行DO( 'etc ...) – Aacini

関連する問題