windows - Hvordan kan jeg bruge findstr med newline regulære udtryk

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg er på Windows DOS prompt. Jeg har logfil, der indeholder log som:


Timestamp: Order received for Item No. 26551
Timestamp: Exception: OutOfRangeException
Timestamp: Message: Inventory Item is not stock. Item No. 23423
Timestamp: Order received for Item No. 23341


Jeg vil udtrække alle varenumre, der har givet en slags undtagelse. Jeg bruger 'findstr' kommando til dette. Hvordan kan jeg bruge newline i mit regulære udtryk? Jeg vil gerne have alle linjer, der har Undtagelsesord og fra næste linje varenr.


nogen hjælp?

Bedste reference


Jeg har opdaget en ukodificeret funktion - FINDSTR CAN match nye linjetegn <CR> og <LF> og fortsæt kampen på efterfølgende linjer. Men søgstrengen skal angives på kommandoen line, skal de nye linjestykker være i variabler, og værdierne skal sendes via forsinket ekspansion.


En anden komplikation er IN () -klausulen om, at en FOR-loop udføres i en separat impliceret CMD-session, og den forsinkede ekspansion skal genaktiveres. Også det! tegn skal undslippes, så de gennemgår den 2. CMD-session.


Denne lille test script gør tricket.


@echo off
setlocal enableDelayedExpansion
if "\%~1"==":doSearch" goto :doSearch

::Define a variable as a LineFeed (0x0A) character
set LF=^


:: The above 2 blank lines MUST be preserved!

::Define a CR variable as a CarriageReturn (0x0D) character
for /f \%\%a in ('copy /Z "\%~dpf0" nul') do set "CR=\%\%a"

set file="test.txt"
for /f "delims=" \%\%A in ('cmd /v:on /c^"findstr /rc:"Item No. .*^!CR^!*^!LF^!.* Exception: " \%file\%^"') do (
  set "ln=\%\%A"
  set "item=!ln:*Item No. =!"
  echo Item No. !item! had an exception
)
exit /b



EDIT 2015-01-11


Jeg læser bare spørgsmålet igen og indser, at jeg har det galt. OP'en ønskede varenummeret, hvor undtagelsesstrengen vises på den forrige linje (se bag søgning), men min løsning kan kun finde varenummeret hvor undtagelse vises på den efterfølgende linje (se fremadrettet søgning).


Desværre er der ingen måde at få FINDSTR til at kigge bag søgning.


I de fleste tilfælde vil jeg slette svaret ovenfor, da det ikke svarer på spørgsmålet. Imidlertid dokumenterer dette svar en ny FINDSTR funktionalitet, som ikke var beskrevet før det kunne være meget nyttigt. Udseendet i fremtiden er tæt nok i konceptet til udseendet bagud, at en person der har brug for det, kan finde svaret via dette spørgsmål, så jeg planlægger at beholde det.


Jeg har en rent scriptbaseret løsning, der kører på en hvilken som helst Windows-maskine fra XP og frem, men den bruger ikke FINDSTR. JREPL.BAT er en regulær kommandolinje, der nemt kan udtrække de ønskede varenumre. [10]


jrepl "Item No. (d+)
.* Exception: " $1 /m /jmatch /f test.txt

Andre referencer 1


Jeg tog et kig på findstr dokumentationen, og jeg tror, ​​det ikke er i stand til at gøre en multiline søgning. [11]


Sandsynligvis skal du bruge mere avancerede værktøjer som awk, eller nogle versioner af grep synes at understøtte multiline regex også.


Du kan se på stackoverflow.com/questions/152708/

Andre referencer 2


Hvis du er på Vista eller Windows 7 (eller hvis du installerer det manuelt på XP), kan du bruge PowerShell til dette:


$resultlist = new-object System.Collections.Specialized.StringCollection
$regex = [regex] '(?m)^.*Exception.*
.*Item No. (d+)'
$match = $regex.Match($subject)
while ($match.Success) {
    $resultlist.Add($match.Groups[1].Value) | out-null
    $match = $match.NextMatch()
} 


$resultlist vil så indeholde en liste over alle varenumre, der følger en linje med Exception i den.

Andre referencer 3


Hvis du kan downloade værktøjer, her er en Ruby for Windows-kommando, du kan bruge. [13]


C:work>ruby -ne "print gets.split.last if /Exception/" file
23423
C:work>type file
Timestamp: Order received for Item No. 26551
Timestamp: Exception: OutOfRangeException
Timestamp: Message: Inventory Item is not stock. Item No. 23423
Timestamp: Order received for Item No. 23341

C:work>ruby -ne "print gets.split.last if /Exception/" file
23423