从输入文件中批处理解析包含特定字符串的行

3

编辑:是的,这必须批量完成。

我需要能够读取输入文件,并解析出仅包含特定字符串的行的某些部分,然后将其写入输出文件。例如:

输入 =

i_NumberOfPersonInTheDataBase=1
i_NumberOfPersonInTheDataBase < 50 AdjTotal=801
MATCH IdentificationResult id=Olivier Score=11419 (NOT_DEFINED-cfv )
02-11-11-07-00 TAG_CAPTURE Badge:CAPTURE - Candidate Found :Olivier
i_NumberOfPersonInTheDataBase=1
i_NumberOfPersonInTheDataBase < 50 AdjTotal=801
MATCH IdentificationResult id=Martin Score=1008 (NOT_DEFINED-cfv )
02-11-11-08-15 TAG_CAPTURE Badge:CAPTURE - Candidate Found :Martin

在包含字符串“IdentificationResult”的行中,我需要返回包含id和Score的字符串。
期望输出 =
id=Olivier Score=11419
id=Martin Score=1008

这是我目前的进展:

这里是我到目前为止的工作:

@setlocal enableextensions enabledelayedexpansion

:: Path of input and output files
set INPUTFILE=DemoFingerOtf-2.log
set OUTPUTFILE=logOutput.txt

:: Clear out the output file
@echo on > %OUTPUTFILE%

:: Read %INPUTFILE% and loop through each line
for /F "tokens=* delims=" %%A in (%INPUTFILE%) do (
    SET my_line=%%A
    SET my_line=!my_line:IdentificationResult=!
    if not !my_line!==%%A (
     call :parse_it
  )   
)

:parse_it
for /F "usebackq tokens=1,2,3,4 delims=~" %%1 in ('%my_line: =~%') do (
    echo %%3 %%4>> %OUTPUTFILE%
)

我现在遇到的问题是,当我运行这个脚本时,会出现') was unexpected at this time错误。当我从输入中删除括号时,就能得到我预期的结果。我已经尝试过添加以下行来删除括号:
:: Read %INPUTFILE% and loop through each line
for /F "tokens=* delims=" %%A in (%INPUTFILE%) do (
    SET my_line=%%A
    SET my_line=!my_line:IdentificationResult=!
    if not !my_line!==%%A (
     SET new_line=%my_line:~0,-18%
     call :parse_it
  )   
)

:parse_it
for /F "usebackq tokens=1,2,3,4 delims=~" %%1 in ('%new_line: =~%') do (
    echo %%3 %%4>> %OUTPUTFILE%
)

我知道在我需要的那几行中,带括号的部分总是恰好18个字符,所以我从末尾删除它们。然而,当我这样做时,由于某种原因,我的输出结果如下:
错误的输出:
id=Olivier Score=11419
id=Olivier Score=11419
id=Olivier Score=11419

所以,我只想解析第一行中的数据,但是我却获取了三次(尽管我的输入中只有两行符合我的条件)。为什么我会多次获取这些数据而不是正确的数据?此外,是否有更好的方法解决我遇到的') was unexpected at this time错误?

4个回答

1
编辑修改后没有尾随空格。没有“ScoreAdjustment”,并且与“John Smith”一起工作 :)
echo off

:: Path of input and output files
set INPUTFILE=DemoFingerOtf-2.log
set OUTPUTFILE=logOutput.txt


setlocal enabledelayedexpansion
for /f "tokens=2,3 delims=^=^(" %%a in ('type "%INPUTFILE%" ^| find /i "IdentificationResult"') do (
                                                                   set $line=Id=%%a=%%b
                                                                   set $line=!$line:ScoreAdjustment=!
                                                                   set $line=!$line:~0,-1!
                                                                   echo !$line!>>%OUTPUTFILE%)

Endlocal

这比我之前做的简单多了,但是我并不完全理解这里发生了什么。具体来说,是什么控制了存储在%%a和%%b中的值? - preppypoof
使用“tokens = 2,3 delims ==(”仅返回翻译文本:每行输出都有尾随空格。 - Endoro
%%a(tokens 2)获取“=”(delims ^=)分隔符[Olivier Score]之间的值,而%%b(tokens 3)获取“)”(delims ^)之前的值[11419]这就是为什么我在%%a之前放置“Id =”,并在后面放置“=”以获得正确的输出的原因 :) - SachaDee
是的,在“(”之前,包括一个空格! - Endoro
不是为我 :) 但你不能称其为“正确的输出”。空格多了一个 :) - Endoro
谢谢您的解释。这对大多数我的输入都有效,但有些输入行有像id=Olivier Score=11419 ScoreAdjustment=801这样的行,因此输出末尾会有一个额外的“ScoreAdjustment”,而我不想要它。是否有适用于这种情况的解决方案? - preppypoof

1
@ECHO OFF &SETLOCAL
for /f "delims=" %%a in ('^<file find "IdentificationResult"') do call:DOit "%%~a"
goto:Eof

:doit
setlocal
set "string=%~1"
set "STring=%string:*IdentificationResult=%"
for /f "Tokens=1,2" %%b in ("%string%") do echo(%%b %%c
exit /b

好的,这并没有回答我的问题,但是这个解决方案完美地解决了我的问题。谢谢! - preppypoof
实际上,我遇到了一个问题。一些数据在“id”字段中有空格,因此我的输出是id=John Smith而不是id=John Smith Score=1337。是否有解决方案可以解决这个问题? - preppypoof
1
看看我的代码新编辑。现在它适用于你所有的情况 :) - SachaDee
在这里使用正则表达式会更好 :) grepsed 或混合 batch/basic 脚本,如 repl.bat - Endoro
@sachadee 使生活更轻松、更愉快。 - Endoro
毫无疑问,使用grep、sed或混合批处理/基本语言或批处理/C语言,@Endoro生活将变得更加轻松,为我们的朋友preppypoof提供帮助。为什么要简单化呢?让我们把它复杂化吧... - SachaDee

1
简单的方法:

    if not !my_line!==%%A (
     ECHO !my_line:~7,-19!>> %OUTPUTFILE%
    )   

你的代码有一些问题,但我赞扬你解决问题的努力。

批处理在标签处不会停止 - 它们只是标记,所以它会直接执行,因此你需要一个

goto :eof

在任何子程序标签之前。

您不能使用数值作为元变量,因此在parse_it中,您需要一个字母,而不是1。您还可以将空格用作delims字符-但它必须被指定为最后一个分隔符(即在关闭"之前)

因此,如果需要,parse_it可以简化为

for /F "tokens=1* delims= " %%q in ("%new_line%") do (
    echo %%r>> %OUTPUTFILE%
)

但总的来说,尝试得不错!

谢谢你实际回答我的问题而不是提供其他解决方案。因为我的输入文件非常大并且它们的速度更快,所以我将使用其中的另一个解决方案,但我很感谢你解释了我的一些错误。 - preppypoof

-1

你没有说明想要使用哪种语言,所以你能做一些类似的事情:

grep IdentificationResult file | awk '{ print $3, $4}' > output.file

1
这个问题被标记为“batch-file”,他的代码是Windows批处理,因此可以推断他想要使用Windows批处理语言。 - aphoria
是的,它必须批量完成。我会在主贴中进行编辑。 - preppypoof
Windows cmd命令行支持grepawk - Endoro
据我所知,在Windows中默认情况下没有grep命令,而且最终用户可能无法访问它。 - preppypoof

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接