1

好的,我有数百个文件,其中有一个文本标题,其中包含一组八个不同变量(名称、主机、年、月、小时、分钟、秒)的一个或多个条目。第一次显示该值时,它看起来像:

@name 4 10
3 4 DHARLAN

此后每次(变量集每个文件可以出现 1 到 100 次)它只显示为:

3 4 DHARLAN

问题在于,在这种情况下,4 可能是 1 到 99 之间的任何值。所以在下一个文件中它可能是:

3 15 DHARLAN

所以实际上每个变量条目是这样的:

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. 变量值(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. 然后第三个 for 循环将解析该行以获取相关变量信息。将行 ( ) 中的第一个、第二个和所有剩余标记检索1,2,*到变量中 (%%X, %%Y, %%Z)
  5. 现在执行逻辑来跟踪变量集。如果已经设置了变量号并且该行与变量号匹配,则保存变量值。否则,如果变量名称匹配,则检索变量编号以在以下几行中进行比较。
  6. 还要增加集合计数,当发现完整集合时,将其写入带有文件名的输出文件。
  7. 重置变量以供下一组使用。
  8. 如果计数不等于 255,则文件格式不正确或变量集不完整。

笔记

该脚本似乎是针对所提出的问题和其中提供的信息的最佳解决方案。我不得不对正在处理的文件做出假设,因此可能需要进行一些修改。如果您想向我们展示要解析的文件的完整示例,这将有助于确定要做什么。

于 2013-02-21T20:27:33.887 回答