Windows Powershell의 Unix tail 해당 명령


349

큰 파일의 마지막 몇 줄을보아야합니다 (일반적인 크기는 500MB-2GB입니다). tailWindows Powershell에 해당하는 Unix 명령 을 찾고 있습니다. 사용 가능한 몇 가지 대안은 다음과 같습니다.

http://tailforwin32.sourceforge.net/

Get-Content [파일 이름] | 객체 선택-마지막 10

나에게는 첫 번째 대안을 사용할 수 없으며 두 번째 대안은 느립니다. 누구나 PowerShell 용 tail의 효율적인 구현을 알고 있습니다.


2
왜 첫 번째 대안을 사용할 수 없는지 말하지 않을 경우 제안 된 내용을 사용할 수 있는지 어떻게 알 수 있습니까?
Gabe

3
sourceforge.net/projects/unxutils/files/unxutils/current/…에tail 제공된 명령을 사용할 수없는 이유는 무엇입니까?
Gabe

1
이것은 외부 실행 파일을 복사 할 수없는 프로덕션 컴퓨터에 있습니다. 이상한 정책들. :) 그것을 도울 수 없습니다. Unxutils 링크에 감사드립니다.
mutelogan

https://devcentral.f5.com/blogs/us/unix-to-powershell-tail 은 이것의 순수한 PoSH 구현을 보여줍니다.
예브게니

Select-Object :를 사용할 필요가 Get-Content [filename] -last 10-tail
없고

답변:


492

-wait파일에 추가 될 때 행을 표시하는 Get-Content와 함께 매개 변수를 사용하십시오 . 이 기능은 PowerShell v1에 존재하지만 어떤 이유로 v2에 제대로 설명되어 있지 않습니다.

여기에 예가 있습니다

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

이 파일을 실행 한 후 파일을 업데이트하고 저장하면 콘솔에 변경 사항이 표시됩니다.


16
흥미 롭군 나는 존재하는 모든 주장이 도움으로도 나타나지만 man gc -par wait매개 변수가 없다고 말합니다. 그러나 이것이 OP가 요구 한 문제를 해결하지 못하고 효율적인 구현도 tail아니라고 tail -f생각합니다. 이것도 마지막 줄을 반환하기 전에 전체 파일을 읽으므로 예상되는 파일 크기에 어려움이 있습니다.
Joey

5
참고로, 이는 PSCX에서 Get-FileTail (별칭 꼬리) 구현이 수행하는 작업입니다. 궁금한 점이 있으면 소스 코드를 확인하십시오. pscx.codeplex.com/SourceControl/changeset/view/78514#1358075
Keith Hill

7
@Joey -Wait는 FileSystem 제공자에만 적용되는 동적 매개 변수입니다. GC는 해당 API를 구현하는 모든 공급자에서 사용할 수 있습니다. 내가 발견 한 문서 이외의 유일한 방법은 (gcm Get-Content)를 사용하는 것입니다. 적절한 공급자 경로 내에서 매개 변수를 사용하십시오. 동적 매개 변수가 표시되지 않으므로 별명 "gc"를 사용하지 마십시오.
JasonMArcher

11
오래 전인 것을 알고 있지만 Get-Content가 작동하기 전에 파일을 쓰고 추가하고 닫으려면 파일에 쓰는 프로세스가 필요합니다. 쓰기 프로세스가 파일을 닫지 않으면 작동하지 않으며 tail -f의 경우에는 그렇지 않습니다.
David Newcomb 2016 년

15
이상하게도 -Wait은 로그 파일에 어떤 방식 으로든 액세스 할 때 (예 : Windows 탐색기에서 로그 파일 선택) 새 줄만 표시합니다. Tail은 새 줄이 내 파일에 기록 될 때 업데이트를 제공합니다. -Wait를 사용하면 파일을 쓰는 동안 새 줄을 표시하지 않고 PowerShell 창을 열어 둘 수 있습니다. 그런 다음 Windows 탐색기에서 파일을 팝업하여 클릭하면 PowerShell이 ​​갑자기 "깨어나"나머지 줄을 따라 잡습니다. 이것이 버그입니까?
JoshL

197

완성도를 높이기 위해 Powershell 3.0에 Get-Content에 -Tail 플래그가 있습니다.

Get-Content ./log.log -Tail 10

파일의 마지막 10 줄을 얻습니다.

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

파일의 마지막 10 줄을 가져오고 더 기다립니다.

또한, 그 * 괜찬아 사용자를위한 참고 대부분의 시스템 별칭 것을 고양이가 가져-내용을하는이 보통 일 때문에

cat ./log.log -Tail 10

@LauraLiparulo 이것은 어떤 방식으로 작동하지 않습니까? 나는 그것을 전에 확실히 사용했습니다.
George Mauer

4
방금 사용 Get-Content .\test.txt -Wait -Tail 1
했는데이

@LauraLiparulo - 또한 나를 위해 작품 :Get-Content -Path .\sync.log -Wait -Tail 10
elika kohen

ISE에서는 while ($ true) / sleep을 사용하고이 스위치로 전환했지만이 또한 전체 ISE를 잠그고 다른 탭에서 스크립트를 실행할 수 없습니다. 새 ISE 인스턴스를 시작해야합니까?
Teoman shipahi

@Teomanshipahi whwat 방식으로 -Wait매개 변수가 작동하지 않습니까?
George Mauer

116

PowerShell 버전 3.0부터 Get-Content cmdlet에는 도움 이되는 -Tail 매개 변수가 있습니다. Get-Content에 대한 technet 라이브러리 온라인 도움말을 참조하십시오 .


1
링크는 여기 다운로드 - microsoft.com/en-us/download/details.aspx?id=34595을 .
Gedrox

4
일부 참고 사항-PS 3.0은 Windows XP 및 Vista에서 사용할 수 없습니다.
tjmoore

1
Dan이 언급 한 기술을 사용하지만 $ PROFILE에 기록합니다. $ PROFILE 메모장으로여십시오. 그런 다음 텍스트 문서에서 새 함수를 작성하십시오. function Tail ($ path) {Get-content -tail 15 -path $ path -wait} 이렇게하면 PowerShell을 시작할 때마다 함수에 액세스 할 수 있습니다.
Jake Nelson

이것이 정답입니다. 현재 허용되는 답변에 언급 된 대기 플래그가 더 이상 작동하지 않습니다.
압둘라 레그 하리

21

나는 여기에 주어진 답변 중 일부를 사용했지만 단지 머리 위로

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

잠시 후 메모리를 씹을 것입니다. 동료가 마지막 날에 이러한 "꼬리"를 남겼으며 800MB까지 올라갔습니다. 유닉스 테일이 같은 방식으로 작동하는지 모르겠지만 의심합니다. 따라서 단기 응용 프로그램에 사용하는 것이 좋지만 조심하십시오.


18

PSCX (PowerShell Community Extensions)Get-FileTailcmdlet을 제공합니다 . 작업에 적합한 솔루션처럼 보입니다. 참고 : 매우 큰 파일로 시도하지는 않았지만 설명에 따르면 내용을 효율적으로 마무리하고 큰 로그 파일을 위해 설계되었습니다.

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
현재 버전에는 매일 비트로 수정되는 버그가 있습니다. 업데이트 된 버전이 출시 될 때까지 최신 비트를 가져 와서 컴파일하는 것이 좋습니다.
Keith Hill

7
버전 2.0은 1GB csv 파일의 마지막 10 개 라인을 표시하는 데 오래 걸리며, Get-Content [filename] | Select-Object -Last 10중단 할 수없는 것과는 다릅니다.
Jader Dias

15

이전 답변에 일부 추가되었습니다. 당신은 UNIX에 사용되는 경우에 당신이 좋아하는 수도 예를 들어, GET-내용에 대해 정의 된 별칭이 있습니다 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

3

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
}

이 작업을 수행하는 대부분의 코드를 찾았 습니다 .


1
-Tail 옵션이있는 Get-Content가 전체 파일을 읽는 것이 사실입니까? 큰 파일에서는 괜찮습니다.
Go

PS 버전에 달려 있다고 생각합니다. 답변을 업데이트했습니다. 당시에 아무것도 설치할 수없는 서버에 붙어있어 위의 코드가 유용했습니다.
hajamie

3

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


0

매우 기본적이지만 애드온 모듈이나 PS 버전 요구 사항없이 필요한 것을 수행합니다.

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


4
큰 파일에는 잔인합니다.
Pecos Bill

내 해결 방법은 : while($true) { Clear-Host; Get-Content <filename> -tail 40; sleep 1 }:)
NoLifeKing

0

아마 대답하기에는 너무 늦었지만 이것을 시도하십시오

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

0

많은 유효한 답변이 있었지만 linux의 tail 과 동일한 구문을 가진 것은 없습니다 . 지속성을 위해 다음 기능을 저장할 수 있습니다 (자세한 내용은 powershell 프로파일 설명서 참조).$Home\Documents\PowerShell\Microsoft.PowerShell_profile.ps1

이것은 당신이 전화를 할 수 있습니다 ...

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

이것은 리눅스 문법에 아주 가깝습니다.

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
    }
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.