Jump to content

Letzte Zeile einer Textdatei auslesen...


Der letzte Beitrag zu diesem Thema ist mehr als 180 Tage alt. Bitte erstelle einen neuen Beitrag zu Deiner Anfrage!

Empfohlene Beiträge

Geschrieben

Hallo,

 

ein schönes Forum habt ihr hier :)

 

Ich habe ein Problem und zwar möchte ich aus einer textdatei (endung .log) nur die letzte Zeile auslesen und in dieser Zeile nach einem Wort suchen (z.B. quit).

 

Wie kann ich das anstellen?

 

Gruß Nils

Geschrieben

Moin,

 

etwas mehr Informationen benötigen wir schon: Was ist das Ziel des Ganzen? Von welcher Scripting-Sprache/-Umgebung reden wir? Geht es um eine neue Lösung oder willst du etwas Bestehendes erweitern? Geht es um eine einmalige oder eine wiederhiolte Aufgabe? Welchen Umfang hat die Logdatei? usw. usf.

 

Gruß, Nils

Geschrieben

Okay, das habe ich vergessen :)

 

Also es geht um die Windows PowerShell.

 

Die Log file kann mehr als 80.000 Zeilen haben, je nach dem wann der Fehler auftritt.

 

Im Moment Prüfe ich immer ob der Service Status auf Running steht und wenn nicht starte ich ihn.

 

Manchmal passiert es aber, das der Service auf Running steht, aber durch ein Fehler der Service nicht mehr richtig arbeitet, in dem Fall taucht in einer Zeile ein quit auf. Danach passiert dann ncihts mehr in der log.

 

Und in dem Fall möchte ich den service halt neustarten.

 

Gruß Nils

 

EDIT: Das einzige was mir so einviel, war mit folgendem Code die Zeilen zu zählen... aber das dauert eigentlich etwas zu lange... desshalb habe ich den ansatz nicht weiter verfolgt.

 

function getZeile ($zeile) {
 $datei = Get-content "C:\Program Files\Service1\service.log"
 $a = 0
 $datei | Foreach-Object { $a++}

 return $a
}

Geschrieben (bearbeitet)

Schade, aber vielleicht ja jemand anders...

 

Den LogParser schaue ich mir mal an

 

Danke

 

EDIT: Habe die Lösung gefunden, um nur die letzte Zeile auszulesen (überspringt leere Zeilen):

 

Get-Content c:\scripts\test.log | Select-Object -last 1

bearbeitet von BNils
Geschrieben
Off-Topic:


[...]
EDIT: Das einzige was mir so einviel, war mit folgendem Code die Zeilen zu zählen... aber das dauert eigentlich etwas zu lange... desshalb habe ich den ansatz nicht weiter verfolgt.

function getZeile ($zeile) {
 $datei = Get-content "C:\Program Files\Service1\service.log"
 $a = 0
 $datei | Foreach-Object { $a++}

 return $a
}



Zur Info:
Das Zeilen zählen geht schneller:

function getZeile(){
 return (Get-content "C:\Program Files\Service1\service.log").count-1
}


Geschrieben (bearbeitet)
if ((Get-Content file.log | Select-Object -Last 1) -match "quit"){
#Your Code here
}

 

Das ist super, dann habe ich eine Pipe weniger :)

 

Danke @Dukel

 

EDIT: Kann es sein, das er mit -last trotzdem vorne anfängt und jede Zeile durchläft bis er bei der letzten ist? Kann man das anders machen, weil es dauert bei meiner log (80.000 Zeilen) lange bis er bei der letzten Zeile ist!

bearbeitet von BNils
Geschrieben

Hallo Nils,

 

mit Get-Content wird leider ebenfalls die gesamte Datei ausgelesen, deswegen dauert es so lange (Get-Content bringt immerhin als Ausgabe ein Array mit allen Zeilen der Datei....).

 

Du mußt das schon direkt mit einem .NET FileStream oder was ähnlichem anpacken. Da kannst Du den Lese-Zeiger direkt aufs Ende setzen und gehst dann zurück, bis du zum erstem Ml auf Character 10 (Line Feed) triffst, das wäre dann der letzte Zeilenumbruch, von da ab liest Du dann die Zeile. So wird von der Datei wirklich nur die letzte Zeile gelesen. Allerdings ist der Powershell-Code sehr häßlich, weil wie gesagt ein .NET-Objekt benutzt werden muß.

 

Hier ein möglicher Code-Entwurf (es gibt wahrscheinlich noch Probleme, wenn die Datei von einem anderen Programm gerade exklusiv geöffnet ist...):

 

$path = "C:\test.txt"
$reader = New-Object System.IO.StreamReader($path, $true)
[long]$pos = $reader.BaseStream.Length - 1
while($pos -gt 0)
{
    $reader.BaseStream.Position = $pos
    if ($reader.BaseStream.ReadByte() -eq 10)  {break}
    $pos--
}
$line = $reader.ReadLine()
$reader.Close()
$line

 

Das gibt die letzte Zeile aus. Auch wenn diese eine Leerzeile ist. Um die letzte nicht-leere Zeile zu bekommen, müßte man ein bisschen was ändern...

 

Gruß,

Philipp

  • 3 Wochen später...
Geschrieben
Hier ein möglicher Code-Entwurf (es gibt wahrscheinlich noch Probleme, wenn die Datei von einem anderen Programm gerade exklusiv geöffnet ist...)

 

Genau das ist nun das Problem :(

 

Aber vielen dank, für die Idee!

 

Gruß Nils

Geschrieben

OK, für einen kompletten Parallel-Zugriff mußt du erst einen System.IO.FileStream öffnen, da kann man entsprechende FileMode/FileAccess Parameter übergeben, den Streamreader erzeugst Du dann auf der Basis vom Filestream.....es müßte ungefähr so gehen:

$path = "C:\test.txt"

$open = [system.IO.FileMode]::Open
$read = [system.IO.FileAccess]::Read
$share =  [system.IO.FileShare]::Read

$stream = New-Object System.IO.FileStream(($path, $open, $read, $share)
$reader = New-Object System.IO.StreamReader($path, $true)

 

...der Rest dann wie gehabt. :cool:

 

Gruß,

Philipp

Geschrieben (bearbeitet)

Das funktioniert nicht, er sagt immer noch das der Prozess von einem anderen Programm geöffnet ist...

 

Hast du noch eine idee :)

 

Gruß Nils

 

EDIT: Ich habe das ganze nun mi tail.exe aus dem Windows Resource Kit gelöst... das funktioniert super :)

 

Trotzdem danke

bearbeitet von BNils
Geschrieben

ich habe mir eine LogDatei mit 140.000 Zeilen erstellt (3-mal das Windowsupdatelog in eine Textdatei kopiert)

 

mit diesem Code bekomme ich auf einem virtuellen Win7-Rechner die letzte Zeile in weniger als 5 Sekunden zurück

 

$inhalt=get-content c:\temp\windowsupdate.log 
$letzteZeile=$($inhalt.length)
$inhalt[$letzteZeile-1]

 

Welche Zeit strebst du denn an?

 

cu

blub

Der letzte Beitrag zu diesem Thema ist mehr als 180 Tage alt. Bitte erstelle einen neuen Beitrag zu Deiner Anfrage!

Schreibe einen Kommentar

Du kannst jetzt antworten und Dich später registrieren. Falls Du bereits ein Mitglied bist, logge Dich jetzt ein.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung jetzt entfernen

  Only 75 emoji are allowed.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor-Fenster leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

×
×
  • Neu erstellen...