it-swarm.com.de

Unix-Tail-Äquivalent-Befehl in Windows Powershell

Ich muss mir die letzten Zeilen einer großen Datei ansehen (typische Größe ist 500MB-2GB). Ich suche ein Äquivalent zum Unix-Befehl tail für Windows Powershell. Einige verfügbare Alternativen sind:

http://tailforwin32.sourceforge.net/

und

Get-Content [Dateiname] | Select-Object -Last 10

Für mich ist es nicht erlaubt, die erste Alternative zu verwenden, und die zweite Alternative ist langsam. Kennt jemand eine effiziente Implementierung von Tail für PowerShell.

320
mutelogan

Verwenden Sie die -wait-Parameter mit Get-Content, der die Zeilen anzeigt, wenn sie zur Datei hinzugefügt werden. Diese Funktion war in PowerShell v1 vorhanden, in v2 jedoch aus irgendeinem Grund nicht gut dokumentiert.

Hier ist ein Beispiel

Get-Content -Path "C:\scripts\test.txt" -Wait

Sobald Sie dies ausgeführt haben, aktualisieren und speichern Sie die Datei. Die Änderungen werden in der Konsole angezeigt.

448
ravikanth

Der Vollständigkeit halber erwähne ich, dass Powershell 3.0 jetzt ein -Tail-Flag für Get-Content hat

Get-Content ./log.log -Tail 10

ruft die letzten 10 Zeilen der Datei ab

Get-Content ./log.log -Wait -Tail 10

ruft die letzten 10 Zeilen der Datei ab und wartet auf weitere

Beachten Sie außerdem, dass die meisten Systemaliasnamen cat für Get-Content für diese * nix-Benutzer gelten, sodass dies normalerweise funktioniert

cat ./log.log -Tail 10
166
George Mauer

Ab PowerShell Version 3.0 verfügt das Cmdlet Get-Content über einen - Tail - Parameter, der Abhilfe schaffen sollte. Siehe die Online-Hilfe der Technet-Bibliothek für Get-Content.

114
Dan Blanchard

Ich habe einige der hier gegebenen Antworten verwendet, aber nur einen Köpfchen darüber

Get-Content -Path Yourfile.log -Tail 30 -Wait 

wird nach einer Weile die Erinnerung auffrischen. Ein Kollege hat am letzten Tag einen solchen "Schwanz" hinterlassen, der auf 800 MB angestiegen ist. Ich weiß nicht, ob sich Unix-Tail genauso verhält (aber ich bezweifle es). Es ist also in Ordnung, es für Kurzzeitanwendungen zu verwenden, aber seien Sie vorsichtig damit.

21
John Lockwood

PowerShell Community Extensions (PSCX) liefert das Get-FileTail Cmdlet . Es sieht nach einer geeigneten Lösung für die Aufgabe aus. Hinweis: Ich habe es nicht mit extrem großen Dateien versucht, aber die Beschreibung besagt, dass es den Inhalt effizient fasst und für große Protokolldateien ausgelegt ist.

NAME
    Get-FileTail

SYNOPSIS
    PSCX Cmdlet: Tails the contents of a file - optionally waiting on new content.

SYNTAX
    Get-FileTail [-Path] <String[]> [-Count <Int32>] [-Encoding <EncodingParameter>] [-LineTerminator <String>] [-Wait] [<CommonParameters>]

    Get-FileTail [-LiteralPath] <String[]> [-Count <Int32>] [-Encoding <EncodingParameter>] [-LineTerminator <String>] [-Wait] [<CommonParameters>]

DESCRIPTION
    This implentation efficiently tails the cotents of a file by reading lines from the end rather then processing the entire file. This behavior is crucial for ef
    ficiently tailing large log files and large log files over a network.  You can also specify the Wait parameter to have the cmdlet wait and display new content
    as it is written to the file.  Use Ctrl+C to break out of the wait loop.  Note that if an encoding is not specified, the cmdlet will attempt to auto-detect the
     encoding by reading the first character from the file. If no character haven't been written to the file yet, the cmdlet will default to using Unicode encoding
    . You can override this behavior by explicitly specifying the encoding via the Encoding parameter.
18
Roman Kuzmin

Nur einige Ergänzungen zu früheren Antworten. Für Get-Content sind Aliase definiert. Wenn Sie beispielsweise an UNIX gewöhnt sind, mögen Sie möglicherweise cat, und es gibt auch type und gc. Also statt

Get-Content -Path <Path> -Wait -Tail 10

du kannst schreiben

# Print whole file and wait for appended lines and print them
cat <Path> -Wait
# Print last 10 lines and wait for appended lines and print them
cat <Path> -Tail 10 -Wait
15
Mikael Sundberg

Unter Verwendung von Powershell V2 und niedriger liest get-content die gesamte Datei, so dass es für mich nicht von Nutzen war. Der folgende Code funktioniert für das, was ich brauchte, obwohl es wahrscheinlich einige Probleme mit der Zeichencodierung gibt. Dies ist effektiv tail -f, aber es kann leicht geändert werden, um die letzten x Bytes oder die letzten x Zeilen zu erhalten, wenn Sie rückwärts nach Zeilenumbrüchen suchen möchten.

$filename = "\wherever\your\file\is.txt"
$reader = new-object System.IO.StreamReader(New-Object IO.FileStream($filename, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read, [IO.FileShare]::ReadWrite))
#start at the end of the file
$lastMaxOffset = $reader.BaseStream.Length

while ($true)
{
    Start-Sleep -m 100

    #if the file size has not changed, idle
    if ($reader.BaseStream.Length -eq $lastMaxOffset) {
        continue;
    }

    #seek to the last max offset
    $reader.BaseStream.Seek($lastMaxOffset, [System.IO.SeekOrigin]::Begin) | out-null

    #read out of the file until the EOF
    $line = ""
    while (($line = $reader.ReadLine()) -ne $null) {
        write-output $line
    }

    #update the last max offset
    $lastMaxOffset = $reader.BaseStream.Position
}

Ich habe den größten Teil des Codes dafür gefunden hier .

3
hajamie

Ich nahm @ hajamies Lösung und packte sie in einen etwas bequemeren Skript-Wrapper.

Ich habe eine Option hinzugefügt, mit der vor dem Ende der Datei von einem Versatz ausgegangen werden kann, damit Sie die schwanzähnliche Funktion zum Lesen einer bestimmten Menge ab dem Ende der Datei verwenden können. Beachten Sie, dass der Offset in Bytes und nicht in Zeilen angegeben ist.

Sie können auch weiterhin auf weitere Inhalte warten.

Beispiele (unter der Annahme, dass Sie dies als TailFile.ps1 speichern):

.\TailFile.ps1 -File .\path\to\myfile.log -InitialOffset 1000000
.\TailFile.ps1 -File .\path\to\myfile.log -InitialOffset 1000000 -Follow:$true
.\TailFile.ps1 -File .\path\to\myfile.log -Follow:$true

Und hier ist das Skript selbst ...

param (
    [Parameter(Mandatory=$true,HelpMessage="Enter the path to a file to tail")][string]$File = "",
    [Parameter(Mandatory=$true,HelpMessage="Enter the number of bytes from the end of the file")][int]$InitialOffset = 10248,
    [Parameter(Mandatory=$false,HelpMessage="Continuing monitoring the file for new additions?")][boolean]$Follow = $false
)

$ci = get-childitem $File
$fullName = $ci.FullName

$reader = new-object System.IO.StreamReader(New-Object IO.FileStream($fullName, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read, [IO.FileShare]::ReadWrite))
#start at the end of the file
$lastMaxOffset = $reader.BaseStream.Length - $InitialOffset

while ($true)
{
    #if the file size has not changed, idle
    if ($reader.BaseStream.Length -ge $lastMaxOffset) {
        #seek to the last max offset
        $reader.BaseStream.Seek($lastMaxOffset, [System.IO.SeekOrigin]::Begin) | out-null

        #read out of the file until the EOF
        $line = ""
        while (($line = $reader.ReadLine()) -ne $null) {
            write-output $line
        }

        #update the last max offset
        $lastMaxOffset = $reader.BaseStream.Position
    }

    if($Follow){
        Start-Sleep -m 100
    } else {
        break;
    }
}
3
Brian Reischl

versuchen Windows Server 2003 Resource Kit Tools

es enthält ein tail.exe, das auf einem Windows-System ausgeführt werden kann.

https://www.Microsoft.com/en-us/download/details.aspx?id=17657

2
starshine wang

Sehr einfach, aber macht das, was Sie brauchen, ohne irgendwelche Zusatzmodule oder PS-Versionsanforderungen:

while ($true) {Clear-Host; gc E:\test.txt | select -last 3; sleep 2 }

1
Jesse

Wahrscheinlich zu spät für eine Antwort, aber versuchen Sie es mit dieser

Get-Content <filename> -tail <number of items wanted>
0
EvosDeMercile