批处理文件在每个文件中变量名称更改时提取值

时间:2013-02-21 18:17:11

标签: loops batch-file cmd extract

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

@name 4 10
3 4 DHARLAN

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

3 4 DHARLAN

问题在于,在这种情况下恰好是4的可以是1和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

非常感谢帮助,甚至建议可以执行此操作的程序。

1 个答案:

答案 0 :(得分:0)

思想

所以......这就是我读你的问题的方法。您有许多具有许多值的文件,并且您希望每个文件输出所有文件变量的单行。每个变量由两行组成。 1.变量声明(name)和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,则文件格式不正确或变量集不完整。
  9. 注释

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