Windows Powershell'de Unix kuyruk eşdeğeri komutu


350

Büyük bir dosyanın son birkaç satırına bakmak zorundayım (tipik boyut 500MB-2GB). tailWindows Powershell için eşdeğer Unix komutunu arıyorum . Kullanılabilecek birkaç alternatif,

http://tailforwin32.sourceforge.net/

ve

İçeriği Al [dosyaadı] | Seç-Nesne -Son 10

Benim için ilk alternatifin kullanılmasına izin verilmiyor ve ikinci alternatif yavaş. Herkes PowerShell için kuyruk verimli bir uygulama biliyor mu?


2
İlk alternatifi neden kullanma izniniz olmadığını söylemezseniz, önerdiğimizi kullanma izniniz olup olmadığını nasıl bilebiliriz?
Gabe

3
Sourceforge.net/projects/unxutils/files/unxutils/current/… 'datail sağlanan komutu kullanamamanızın herhangi bir nedeni ?
Gabe

1
bu, herhangi bir harici yürütülebilir dosyayı kopyalamama izin verilmediği bir üretim makinesinde. Bazı tuhaf politikalar. :) Yardım edemem. Unxutils bağlantısı için teşekkürler.
mutelogan

https://devcentral.f5.com/blogs/us/unix-to-powershell-tail , bunun saf PoSH uygulamasını gösterir.
Yevgeniy

Select-Object kullanmaya gerek yok: -f için Get-Content [filename] -last 10ekleyin-tail
MortenB

Yanıtlar:


492

-waitParametreyi, satırları dosyaya eklenirken görüntüleyen Get-Content ile kullanın . Bu özellik PowerShell v1'de mevcuttu, ancak bazı nedenlerden dolayı v2'de iyi belgelenmedi.

İşte bir örnek

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

Bunu çalıştırdığınızda, dosyayı güncelleyin ve kaydedin; değişiklikleri konsolda göreceksiniz.


16
İlginç. Var olan tüm argümanların da yardımda göründüğünü düşünürdüm, ancak man gc -par waitbana parametre olmadığını söylerdim. Ama bence bu OP'nin sahip olduğu sorunu çözmedi, çünkü istedikleri gibi tail, tail -fverimli bir uygulama da değil . Bu da son satırları döndürmeden önce tüm dosyayı okuduğundan, bekledikleri dosya boyutları için acı vericidir.
Joey

5
Bilginize, Get-FileTail (diğer ad kuyruğu) uygulamasının PSCX'te yaptığı şey budur. Merak ediyorsanız kaynak koduna bakabilirsiniz: pscx.codeplex.com/SourceControl/changeset/view/78514#1358075
Keith Hill

7
@Joey -Wait, yalnızca FileSystem sağlayıcısı için geçerli olan dinamik bir parametredir. GC, söz konusu API'yı uygulayan herhangi bir sağlayıcıda kullanılabilir. Bunları keşfetmeyi bildiğim belgelerin yanı sıra tek yol (gcm Get-Content) kullanmaktır. Uygun sağlayıcı yolundan parametreler. "Gc" takma adını kullanmayın, çünkü dinamik parametreler görünmez.
JasonMArcher

11
Bir süre önce olduğunu biliyorum, ancak bu işlem Get-Content çalışmaya başlamadan önce dosyayı açmak, eklemek, kapatmak için dosyaya yazma gerektirir. Yazma işlemi asla dosyayı kapatmazsa, kuyruk -f ile durum böyle olmaz.
David Newcomb

15
Garip bir şekilde, -Bekle sadece bir günlük dosyasına bir şekilde eriştiğimde (Windows Gezgini'nde seçmek gibi) yeni satırları gösteriyor. Tail, dosyama yeni satırlar yazılırken güncellemeler sağlar. -Wait ile, dosyaya yazılırken yeni satırlar göstermeyen bir PowerShell penceresini açık bırakabilirim. Sonra açılır ve Windows Gezgini'nde dosyayı tıklarsam, aniden PowerShell "uyanır" ve kalan satırları yakalar. Bu bir hata mı?
JoshL

199

Tamlık için Powershell 3.0'ın artık Get-Content'de bir -Tail bayrağı bulunduğunu söyleyeceğim.

Get-Content ./log.log -Tail 10

dosyanın son 10 satırını alır

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

dosyanın son 10 satırını alır ve daha fazlasını bekler

Ayrıca, bu * Nix kullanıcıları için, not çoğu sistem takma o kedi Get-Content için bu genellikle işlerin böylece

cat ./log.log -Tail 10

@LauraLiparulo bu ne şekilde çalışmıyor? Kesinlikle daha önce kullandım.
George Mauer

4
Ben sadece kullandım ve bu formatta spot çalıştıGet-Content .\test.txt -Wait -Tail 1
Coops

@LauraLiparulo - Benim için de çalışır:Get-Content -Path .\sync.log -Wait -Tail 10
elika kohen

İMKB'de ($ true) / sleep kullanırken kullanıyordum ve buna geçtim, ancak bu da tüm İMKB'yi kilitliyor ve diğer sekmelerde komut dosyası çalıştıramıyor. Yeni bir İMKB örneği başlatmalı mıyım?
Teoman shipahi

@Teomanshipahi -WaitParametre sizin için ne işe yaramadı?
George Mauer

116

PowerShell sürüm 3.0'dan itibaren Get-Content cmdlet'inde yardımcı olması gereken bir -Tail parametresi vardır. Bkz Al-İçerik için technet kütüphane çevrimiçi yardım.


1
Buradan indirmek için bağlantı - microsoft.com/en-us/download/details.aspx?id=34595 .
Gedrox

4
Bazıları için not - PS 3.0, Windows XP ve Vista için kullanılamaz.
tjmoore

1
Dan'ın bahsettiği tekniği kullanıyorum ama $ PROFILE'ma kaydediyorum. $ PROFILE not defteri ile açın. Daha sonra metin belgesinde yeni bir işlev oluşturun: function Tail ($ path) {Get-content -tail 15 -path $ path -wait} Bu şekilde PowerShell'i her başlattığınızda işleve erişebilirsiniz.
Jake Nelson

Bu kabul edilen cevap olmalı. -Şu anda kabul edilen cevapta belirtilen bekleme bayrağı artık çalışmıyor.
Abdullah Leghari

21

Burada verilen cevaplardan bazılarını kullandım ama sadece

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

bir süre sonra hafızayı çiğner. Bir meslektaşım son bir gün içinde böyle bir "kuyruk" bıraktı ve 800 MB'a kadar çıktı. Unix kuyruğunun aynı şekilde davranıp davranmadığını bilmiyorum (ama bundan şüpheliyim). Bu nedenle kısa süreli uygulamalar için kullanmak iyidir, ancak dikkatli olun.


18

PowerShell Topluluk Uzantıları (PSCX) sağlar Get-FileTailcmdlet'ini . Görev için uygun bir çözüm gibi görünüyor. Not: Son derece büyük dosyalarla denemedim, ancak açıklama içeriği etkili bir şekilde izlediğini ve büyük günlük dosyaları için tasarlandığını söylüyor.

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.

1
Mevcut sürümde günlük bitlerle düzeltilen bir hata var. En son bitleri almanızı ve en azından güncellenmiş bir sürüm çıkana kadar bunları derlemenizi tavsiye ederim.
Keith Hill

7
Sürüm 2.0, 1GB csv dosyasının son 10 satırını göstermek için yaş alır ve Get-Content [filename] | Select-Object -Last 10ondan farklı olarak iptal edilemez
Jader Dias

15

Sadece önceki cevaplara bazı eklemeler. UNIX için kullanılıyorsa Hoşunuza gidebilecek örneğin, Al-İçerik için tanımlanmış diğer adları vardır catve de vardır typeve gc. Yani yerine

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

Yazabilirsin

# 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

3

Powershell V2 ve aşağısını kullanarak get-content tüm dosyayı okur, bu yüzden benim için hiçbir faydası yoktu. Karakter kodlamaları ile ilgili bazı sorunlar olsa da, aşağıdaki kod ben gerekli için çalışır. Bu etkili bir şekilde kuyruk -f'dir, ancak satır sonlarını geriye doğru aramak istiyorsanız son x baytı veya son x satırını almak için kolayca değiştirilebilir.

$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
}

Bunu yapmak için kod çoğu buldum burada .


1
-Tail seçeneğiyle Get-Content'in tüm dosyayı okuduğu doğru mu? Büyük dosyalarda benim için sorun değil.
Govert

PS sürümüne bağlı olduğuna inanıyorum. Cevabı güncelledim. O zaman bir şey yükleme yeteneği olmadan bir sunucuda sıkışmış, bu yüzden yukarıdaki kod yararlı oldu.
hajamie

3

@ Hajamie'nin çözümünü aldım ve biraz daha uygun bir senaryo sarıcısına tamamladım.

Dosyanın sonundan önce bir ofsetten başlamak için bir seçenek ekledim, böylece dosyanın sonundan belirli bir miktarı okumak için kuyruk benzeri işlevselliği kullanabilirsiniz. Uzaklığın satırlar değil bayt cinsinden olduğunu unutmayın.

Ayrıca daha fazla içerik beklemeye devam etme seçeneği de vardır.

Örnekler (bunu TailFile.ps1 olarak kaydettiğinizi varsayarsak):

.\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

Ve işte senaryonun kendisi ...

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;
    }
}


0

Çok basit, ancak herhangi bir eklenti modülü veya PS sürümü gereksinimleri olmadan ihtiyacınız olanı yapar:

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


4
Bu büyük dosyalarda acımasız.
Pecos Bill

Geçici while($true) { Clear-Host; Get-Content <filename> -tail 40; sleep 1 }
çözümüm

0

Muhtemelen bir cevap için çok geç ama bunu dene

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

0

Birçok geçerli cevap var, ancak hiçbiri linux'daki kuyrukla aynı sözdizimine sahip değil . Aşağıdaki işlev kalıcılığınız için saklanabilir ( daha fazla ayrıntı için powershell profilleri belgelerine bakın).$Home\Documents\PowerShell\Microsoft.PowerShell_profile.ps1

Bu aramanızı sağlar ...

tail server.log
tail -n 5 server.log
tail -f server.log
tail -Follow -Lines 5 -Path server.log

linux sözdizimine oldukça yakın geliyor.

function tail {
<#
    .SYNOPSIS
        Get the last n lines of a text file.
    .PARAMETER Follow
        output appended data as the file grows
    .PARAMETER Lines
        output the last N lines (default: 10)
    .PARAMETER Path
        path to the text file
    .INPUTS
        System.Int
        IO.FileInfo
    .OUTPUTS
        System.String
    .EXAMPLE
        PS> tail c:\server.log
    .EXAMPLE
        PS> tail -f -n 20 c:\server.log
#>
    [CmdletBinding()]
    [OutputType('System.String')]
    Param(
        [Alias("f")]
        [parameter(Mandatory=$false)]
        [switch]$Follow,

        [Alias("n")]
        [parameter(Mandatory=$false)]
        [Int]$Lines = 10,

        [parameter(Mandatory=$true, Position=5)]
        [ValidateNotNullOrEmpty()]
        [IO.FileInfo]$Path
    )
    if ($Follow)
    {
        Get-Content -Path $Path -Tail $Lines -Wait
    }
    else
    {
        Get-Content -Path $Path -Tail $Lines
    }
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.