1

OK、8 つの異なる変数 (名前、ホスト、年、月、時、分、秒) のセットの 1 つ以上のエントリを含むテキスト ヘッダーを持つファイルが何百もあります。値が最初に表示されるときは、次のようになります。

@name 4 10
3 4 DHARLAN

この後は毎回 (変数セットはファイルごとに 1 ~ 100 回出現する可能性があります)、次のようにのみ表示されます。

3 4 DHARLAN

問題は、この場合にたまたま 4 が 1 から 99 の間の任意の値になる可能性があることです。したがって、次のファイルでは次のようになります。

3 15 DHARLAN

したがって、実際には eavh 変数のエントリは次のようになります。

3 ## <value>

## は、ヘッダーの前半で次のように決定されます。

@name ## X

FOR /F TOKENS がどのように機能して近いものを取得するかについて、私は十分に理解していません。

What I need is to parse a directory and end up with a file something like:
<filenameA> <name1> <host1> <year1> <month1> <day1> <hour1> <minute1> <second1>
<filenameA> <name2> <host2> <year2> <month2> <day2> <hour2> <minute2> <second2>
<filenameB> <name1> <host1> <year1> <month1> <day1> <hour1> <minute1> <second1>
...

私がこれまでに持っているもの:

FOR /f "tokens=*" %%i IN ('dir /a-d /s /b') DO call :findfile "%%i"

:findfile
REM Print Filename
FINDSTR /B /M "#UGC">>output.txt
REM set Name Variable, need 2nd word (7th & if exists (8th) character) from this line only
FINDSTR /B "@name">%%n
REM Find all lines with name variable
FINDSTR /B "3 %n%">>output.txt

これを行うことができるプログラムへの提案でさえ、助けていただければ幸いです。

4

1 に答える 1

0

考え

だから...これが私があなたの質問を読む方法です。多くの値を持つ多くのファイルがあり、ファイルごとに、すべてのファイルの変数の 1 行を出力したいとします。各変数は 2 行で構成されます。1. 変数宣言 (名前) および 2. 変数値 (DHARLAN)。これらの行は、番号 (1 ~ 99) で関連付けられています。これは正しいです?

これで始められるはずです...

@echo off
setlocal EnableExtensions EnableDelayedExpansion

<nul set /p "=">output.txt
for /f "delims=" %%F in ('dir /a:-d /b /s') do if exist "%%~fF" (
    set "name="
    set "namenum="
    set "host="
    set "hostnum="
    set "year="
    set "yearnum="
    set "month="
    set "day="
    set "daynum="
    set "monthnum="
    set "hour="
    set "hournum="
    set "minute="
    set "minutenum="
    set "second="
    set "secondnum="
    set "count=0"
    for /f "usebackq delims=" %%L in ("%%~fF") do (
        for /f "tokens=1,2,3*" %%X in ("%%L") do (
            if "%%Y"=="!namenum!" set "name=%%Z" & set /a "count+=1"
            if "%%Y"=="!hostnum!" set "host=%%Z" & set /a "count+=2"
            if "%%Y"=="!yearnum!" set "year=%%Z" & set /a "count+=4"
            if "%%Y"=="!monthnum!" set "month=%%Z" & set /a "count+=8"
            if "%%Y"=="!daynum!" set "day=%%Z" & set /a "count+=16"
            if "%%Y"=="!hournum!" set "hour=%%Z" & set /a "count+=32"
            if "%%Y"=="!minutenum!" set "minute=%%Z" & set /a "count+=64"
            if "%%Y"=="!secondnum!" set "second=%%Z" & set /a "count+=128"
            if /i "%%X"=="@name" set "namenum=%%Y"
            if /i "%%X"=="@host" set "hostnum=%%Y"
            if /i "%%X"=="@year" set "yearnum=%%Y"
            if /i "%%X"=="@month" set "monthnum=%%Y"
            if /i "%%X"=="@day" set "daynum=%%Y"
            if /i "%%X"=="@hour" set "hournum=%%Y"
            if /i "%%X"=="@minute" set "minutenum=%%Y"
            if /i "%%X"=="@second" set "secondnum=%%Y"
            if "!count!" equ "255" (
                echo %%~nxF !name! !host! !year! !month! !day! !hour! !minute! !second!>>output.txt
                set "name="
                set "namenum="
                set "host="
                set "hostnum="
                set "year="
                set "yearnum="
                set "month="
                set "day="
                set "daynum="
                set "monthnum="
                set "hour="
                set "hournum="
                set "minute="
                set "minutenum="
                set "second="
                set "secondnum="
                set "count=0"
            )
        )
    )
)

goto :eof

:End
endlocal

アップデート

上記のスクリプトをコメント付きで更新したものを次に示します。cdまた、セットアップセクションとコマンドを使用して、以下のコメントに対処する必要があります。

@echo off
setlocal EnableExtensions EnableDelayedExpansion

:: Setup
set "ResultsFolder=results"
set "ExportFile=output.txt"

:: Set the Working Directory
cd data

:: Verify that the Results folder exists
if not exist "%ResultsFolder%\*" md "%ResultsFolder%"
set "OutputFile=%ResultsFolder%\%ExportFile%"

:: Empty the results file.
<nul set /p "=">%OutputFile%

:: Loop through the files /a:-d in the directory and its subdirectories /s.
for /f "delims=" %%F in ('dir /a:-d /b /s') do if exist "%%~fF" (
    call :Reset
    rem Loop through the file contents and parse each line.
    for /f "usebackq delims=" %%L in ("%%~fF") do (
        for /f "tokens=1,2,3*" %%X in ("%%L") do (
            rem Keep track of the variables.
            if "%%Y"=="!namenum!"   set "name=%%Z"   & set /a "count+=1"
            if "%%Y"=="!hostnum!"   set "host=%%Z"   & set /a "count+=2"
            if "%%Y"=="!yearnum!"   set "year=%%Z"   & set /a "count+=4"
            if "%%Y"=="!monthnum!"  set "month=%%Z"  & set /a "count+=8"
            if "%%Y"=="!daynum!"    set "day=%%Z"    & set /a "count+=16"
            if "%%Y"=="!hournum!"   set "hour=%%Z"   & set /a "count+=32"
            if "%%Y"=="!minutenum!" set "minute=%%Z" & set /a "count+=64"
            if "%%Y"=="!secondnum!" set "second=%%Z" & set /a "count+=128"
            if /i "%%X"=="@name"   set "namenum=%%Y"
            if /i "%%X"=="@host"   set "hostnum=%%Y"
            if /i "%%X"=="@year"   set "yearnum=%%Y"
            if /i "%%X"=="@month"  set "monthnum=%%Y"
            if /i "%%X"=="@day"    set "daynum=%%Y"
            if /i "%%X"=="@hour"   set "hournum=%%Y"
            if /i "%%X"=="@minute" set "minutenum=%%Y"
            if /i "%%X"=="@second" set "secondnum=%%Y"
            rem When a full set is reached print it out.
            if "!count!" equ "255" (
                echo %%~nxF !name! !host! !year! !month! !day! !hour! !minute! !second!>>%OutputFile%
                call :Reset
            )
            if "!count!" gtr "255" (
                echo %%~nxF: Incomplete Set Encountered.  Stopping parsing of this file, continuing to the next.
                rem You can also use other validations to identify incomplete sets.
            )
        )
    )
)

goto :eof

:: Reset all of the variables for the next set.
:Reset
set "name="
set "namenum="
set "host="
set "hostnum="
set "year="
set "yearnum="
set "day="
set "daynum="
set "month="
set "monthnum="
set "hour="
set "hournum="
set "minute="
set "minutenum="
set "second="
set "secondnum="
set "count=0"
goto :eof

:End
endlocal

概要

これは、スクリプトの実行内容とその動作の概要です。

  1. Main for ループは、現在の作業ディレクトリ内にあるすべてのファイルをループします。dir /a:-d /b /s
  2. このループ内で、最初にファイル変数を追跡するために必要な変数を設定します。:Reset
  3. 次の for ループは、ファイルを開き、ファイルの各行を読み取ります。%%L
  4. 3 番目の for ループは、関連する変数情報について行を解析します。行 ( ) から 1 番目、2 番目、および残りのすべてのトークン1,2,*を変数 (%%X、%%Y、%%Z) に取得します。
  5. ここで、変数セットを追跡するロジックを実行します。変数番号が設定されていて、この行が変数番号と一致する場合は、変数値を保存します。変数名が一致する場合は、次の行で比較のために変数番号を取得します。
  6. また、セット カウント数をインクリメントし、完全なセットが検出されたら、それをファイル名と共に出力ファイルに書き込みます。
  7. 次のセットで使用するために変数をリセットします。
  8. カウントが 255 に等しくない場合、ファイルの形式が正しくないか、変数のセットが不完全です。

ノート

このスクリプトは、提示された質問とそこで提供される情報に対する最良の解決策と思われるものです。処理中のファイルについて想定する必要があったため、いくつかの変更が必要になる場合があります。解析するファイルの完全な例を表示したい場合は、何をすべきかを判断するのに役立ちます。

于 2013-02-21T20:27:33.887 に答える