2012-03-30 4 views
0

Ich habe eine Textdatei filter.tmp enthält zwei Arten von Linien zu filtern, zeigt dies den Unterschied:Filtering Datei reg exp und verketten bestimmte Linien zusammen (Eingabeaufforderung)

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

Was muss ich sie wird Zeilen anhängen Text zusammen wie diese enthält, und wenn die Zeilennummer enthält nur ihn zu Ausgabedatei:

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 enthält so etwas wie:

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

filter.out sollte wie folgt aussehen:

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

Mir ist klar, dies ist sehr einfach, aber ich kann es einfach nicht funktioniert. Wenn ich darüber nachdenke, wäre es viel einfacher, C++ zu verwenden.

+0

Warum nicht C++ verwenden, dann? –

+0

Ich denke, dass eine C++ - Lösung komplexer als die Batch-Datei sein kann. Es könnte jedoch einfacher zu verstehen sein. – Joey

+0

Bali C, ich wollte, aber es war keine IDE auf der Arbeitsstation installiert und ich hatte nur begrenzte Benutzerrechte, so konnte ich keine installieren – rluks

Antwort

1

Dies ist eine ziemlich wortgetreue Übersetzung Ihres Pseudocodes und Ihrer Regexes, basierend auf der Annahme, dass »enthält Zahlen« wirklich »beginnt mit zwei Ziffern «(das ist, was Ihre regulären Ausdrücke zeigen):

@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!) 

Diese mehrere Dinge verwendet. Vor allem brauchen wir eine verzögerte Expansion, die es uns ermöglicht, Umgebungsvariablen innerhalb der Schleife zu manipulieren. Dann iterieren wir über die Zeilen in der Datei mit for /f. Beachten Sie, dass dabei leere Zeilen in der Datei übersprungen werden. Dies kann jedoch nicht verhindert werden. Innerhalb der for /f Schleife die Variable Line hält die aktuelle Zeile und Prev die vorherige (wenn es eine vorherige). Ich vertauschte die then und else Zweige der Bedingung, da Zahlen am Anfang der Zeile einfacher zu überprüfen sind als Nicht-Nummern.

Mit der echo werden Sie feststellen, dass ich die Umleitung an den Anfang der Zeile verschoben habe; Dies verhindert, dass nachfolgende Zahlen in Prev oder Line Auswirkungen auf die Umleitung haben (und auch nachfolgende Leerzeichen vermeiden).

Wenn Sie Powershell nicht abgeneigt sind, können Sie das folgende verwenden:

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

Danke Joye, gibt es nur ein Problem mit Echo, wo Variable nicht festgelegt ist und es druckt das Standard-Echo Nachricht in filter.out Ich reparierte es mit ... "echo.! Prev!" aber das druckt leere Zeilen. Also muss ich daran denken sie zu entfernen. Powershell war eigentlich meine erste Idee, aber ich habe keine Rechte, irgendetwas zu installieren .... – rluks

+0

Sollte jetzt funktionieren. Ich nehme an, das war der Fall, wenn die erste Zeile mit einer Nummer begann, oder? – Joey

Verwandte Themen