web-dev-qa-db-ja.com

Windows PowershellのUnix末尾相当コマンド

私は大きなファイルの最後の数行を見なければなりません(典型的なサイズは500MB - 2GBです)。私は、Windows Powershell用のUnixコマンドtailと同等のものを探しています。利用可能ないくつかの選択肢があります:

http://tailforwin32.sourceforge.net/

そして

Get-Content [ファイル名] |選択オブジェクト最後10

私にとっては、最初の選択肢を使用することは許可されていません、そして2番目の選択肢は遅いです。誰もがPowerShell用のtailの効率的な実装を知っていますか。

308
mutelogan

Get-Contentで-waitパラメータを使用すると、ファイルに追加された行が表示されます。この機能はPowerShell v1にはありましたが、何らかの理由でv2には十分に記載されていませんでした。

これが例です

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

これを実行したら、ファイルを更新して保存すると、コンソールに変更が表示されます。

434
ravikanth

完全を期すために、Powershell 3.0ではGet-Contentに-Tailフラグが追加されました。

Get-Content ./log.log -Tail 10

ファイルの最後の10行を取得

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

ファイルの最後の10行を取得し、さらに待つ

また、これらの* nixユーザにとって、ほとんどのシステムはGet-Contentにエイリアスcatを付けているので、これは通常うまくいきます。

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

PowerShellバージョン3.0以降、Get-Contentコマンドレットには - Tailパラメータが役立ちます。 Get-Contentについては、 technetライブラリのオンラインヘルプを参照してください。

113
Dan Blanchard

私はここで与えられた答えのいくつかを使いました、しかしそれだけで頭を上げます

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

しばらくすると記憶を噛みます。同僚がこの1日かけてそのような「尾」を残し、それは800 MBに達しました。 Unixのtailが同じように振る舞うかどうかはわかりません(しかしそれは疑います)。そのため、短期間のアプリケーションに使用しても構いませんが、注意してください。

21
John Lockwood

PowerShellコミュニティ拡張(PSCX)Get-FileTailコマンドレット を提供します。それはそのタスクに対する適切な解決策のように見えます。注:私は極端に大きなファイルでそれを試していませんでしたが、説明はそれが効率的に内容を追いかけて、それが大きなログファイルのために設計されていると言います。

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

前回の回答にいくつか追加します。 Get-Contentに定義されたエイリアスがあります。たとえば、UNIXに慣れている場合はcatが好きで、またtypegcもあります。だから代わりに

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

あなたは書ける

# 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

Powershell V2以下を使って、get-contentはファイル全体を読むので、それは私には役に立ちませんでした。次のコードは私が必要としていたものに対して動作しますが、文字エンコーディングに関してはおそらくいくつかの問題があります。これは実質的にtail -fですが、最後のxバイト、または改行を逆方向に検索したい場合は最後のx行を取得するように簡単に変更できます。

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

私はこれをするためのコードの大部分 をここに見つけました

3
hajamie

私は@ hajamieの解決策を取り、もう少し便利なスクリプトラッパーにまとめました。

ファイルの末尾の前にオフセットから開始するオプションを追加したので、ファイルの末尾から一定量を読み取るという末尾のような機能を使用できます。オフセットは、行数ではなくバイト数です。

さらにコンテンツを待ち続けるオプションもあります。

例(これをTailFile.ps1として保存したとします):

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

そして、これがスクリプトそのものです。

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

Windows Server 2003 Resource Kit Toolsを試す

windowsシステムで実行できるtail.exeが含まれています。

https://www.Microsoft.com/ja-jp/download/details.aspx?id=17657

2
starshine wang

非常に基本的ですが、アドオンモジュールやPSのバージョン要件を必要とせずに必要なことを行います。

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

1
Jesse

回答者にはおそらく手遅れですが、これを試してください

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