windows - Filtrerende fil ved hjælp af reg exp og sammenkoble visse linjer sammen (kommandoprompt)

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg skal filtrere en tekstfil filter.tmp, der indeholder to typer af linjer, dette viser forskellen:


findstr /r "^[0-9][0-9]*.*$" filter.tmp > filter-numbers.tmp
findstr /r "^[^0-9][^0-9]*.*$" filter.tmp > filter-text.tmp


Hvad jeg skal gøre er at tilføje linjer, der indeholder tekst sammen som dette, og hvis linjen indeholder nummer, skal du blot lægge det til outputfil:


IF "current line" contains text THEN
previous line = concatenate "previous line" + "/" + "current line"
ELSE
echo "previous line" >> filter.out
echo "current line" >> filter.out


filter.tmp indeholder noget som:


Hello
World
Foo
Bar
45: this is some line
Trouble
with code
66: another line


filter.out skal ligne:


Hello/World/Foo/Bar
45: this is some line
Trouble/with code
66: another line


Jeg er klar over, at dette er meget simpelt, men jeg kan bare ikke få det til at fungere. Da jeg tænker på det, ville det være meget nemmere at bruge C ++ ....

Bedste reference


Dette er en ret ordentlig oversættelse af din pseudokode og dine regexes, baseret på antagelsen om at »indeholder tal« betyder virkelig »starter med to cifre« (hvilket er hvad dine regexes viser):


@echo off
setlocal enabledelayedexpansion
set Prev=
for /f "delims=" \%\%x in (filter.tmp) do (
    set "Line=\%\%x"
    if "!Line:~0,2!" GEQ "00" if "!Line:~0,2!" LEQ "99" (
        if not "!Prev!"=="" (>>filter.out echo !Prev!)
        >>filter.out echo !Line!
        set Prev=
    ) else (
        if "!Prev!"=="" (set "Prev=!Line!") else (set "Prev=!Prev!/!Line!")
    )
)
if not "!Prev!"=="" (>>filter.out echo !Prev!)


Dette bruger flere ting. Først og fremmest har vi brug for forsinket ekspansion, som gør det muligt for os at manipulere miljøvariabler inden for løkken. Så gentager vi linjerne i filen med for /f. Bemærk at dette vil springe over tomme linjer i filen, men du kan ikke undgå det. Inde i for /f løkken holder variablen Line den aktuelle linje og Prev den forrige (hvis der har været en tidligere). Jeg byttede betingelserne then og else af betingelsen, da tal ved starten af ​​linjen er nemmere at kontrollere end ikke-tal.


Med echo vil du bemærke, at jeg flyttede omdirigeringen til starten af ​​linjen, for at forhindre efterfølgende numre i Prev eller Line at have en effekt på omdirigering (og også for at undgå efterfølgende rum).


Hvis du ikke er negativ for PowerShell, kan du bruge følgende:


$(switch -Regex -File filter.tmp {
    '^D'    { if ($prev) { $prev += "/$\_" } else { $prev = $\_ } }
    '^d{2}' { if ($pref) {$prev}; $\_; $prev = '' }
}
if ($prev) { $prev }
) | Set-Content filter.out