# encoding: ascii # api: powershell # title: tail # description: since this post i’m out on github :) # version: 0.1 # type: function # author: greg zakharov # license: CC0 # function: Get-FileTail # x-poshcode-id: 4844 # x-archived: 2014-04-10T15:44:07 # x-published: 2014-01-27T13:06:00 # # #requires -version 2.0 Set-Alias tail Get-FileTail function Get-FileTail { <# .NOTES Author: greg zakharov #> [CmdletBinding(DefaultParameterSetName="FileName", SupportsShouldProcess=$true)] param( [Parameter(Mandatory=$true, Position=0, ValueFromPipeline=$true)] [ValidateScript({Test-Path $_})] [String]$FileName, [Parameter(Position=1)] [ValidateRange(1, 65535)] [UInt16]$NumberOfLines = 10, [Parameter(Position=2)] [Text.Encoding]$Encoding = [Text.Encoding]::Default, [Parameter(Position=3)] [String]$Delims = "`r`n" ) begin { $FileName = cvpa $FileName function get([String]$path, [Int64]$tokens, [Text.Encoding]$enc, [String]$delims) { [Int32]$szChar = $enc.GetByteCount("`n") [Byte[]]$buff = $enc.GetBytes($delims) try { $fs = New-Object IO.FileStream($path, [IO.FileMode]::Open, [IO.FileAccess]::Read) [Int64]$tknCount = 0 [Int64]$endReads = $fs.Length / $szChar for ([Int64]$pos = $szChar; $pos -lt $endReads; $pos += $szChar) { [void]$fs.Seek(-$pos, [IO.SeekOrigin]::End) [void]$fs.Read($buff, 0, $buff.Length) if ($enc.GetString($buff) -eq $delims) { $tknCount++ if ($tknCount -eq $tokens) { [Byte[]]$retBuff = New-Object "Byte[]" ($fs.Length - $fs.Position) [void]$fs.Read($retBuff, 0, $retBuff.Length) return $enc.GetString($retBuff) } } } $fs.Seek(0, [IO.SeekOrigin]::Begin) $buff = New-Object "Byte[]" $fs.Length [void]$fs.Read($buff, 0, $buff.Length) return $enc.GetString($buff) } finally { if ($fs -ne $null) {$fs.Close()} } } } process { if ($PSCmdlet.ShouldProcess($FileName, "Reads last $($NumberOfLines) strings of")) { get $FileName $NumberOfLines $Encoding $Delims } } end {} }