Utils/tac.ps1
|
Register-GnuUtil @{ Name = 'tac' Category = 'Viewing file contents' Synopsis = 'Concatenate and print files in reverse.' Usage = @('tac [OPTION]... [FILE]...') Description = @('Write each FILE to standard output, last line first.', '', 'With no FILE, or when FILE is -, read standard input.') FileOperands = $true OpenErrorFormat = "failed to open '{0}' for reading: {1}" ReadErrorFormat = "{0}: read error: {1}" Options = @( @{ Short = 'b'; Long = 'before'; Help = 'attach the separator before instead of after' } @{ Short = 'r'; Long = 'regex'; Help = 'interpret the separator as a regular expression' } @{ Short = 's'; Long = 'separator'; Arg = 'STRING'; Help = 'use STRING as the separator instead of newline' } ) Notes = @('PowerShell note: -r uses .NET regular expression syntax.') } function script:ConvertTo-GnuReversedRecord { <# .SYNOPSIS Reverses the separator-delimited records of a text (tac semantics). #> param( [Parameter(Mandatory)][AllowEmptyString()][string]$Text, [Parameter(Mandatory)][string]$Pattern, [switch]$Before ) if ([string]::IsNullOrEmpty($Text)) { return '' } $records = New-Object 'System.Collections.Generic.List[string]' $start = 0 foreach ($match in [regex]::Matches($Text, $Pattern)) { if ($match.Length -eq 0) { continue } if ($Before) { if ($match.Index -gt $start) { $records.Add($Text.Substring($start, $match.Index - $start)) } $start = $match.Index } else { $end = $match.Index + $match.Length $records.Add($Text.Substring($start, $end - $start)) $start = $end } } if ($start -lt $Text.Length) { $records.Add($Text.Substring($start)) } $records.Reverse() -join $records } |