Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Unix like command for tac?

150 views
Skip to first unread message

Duncan Smith

unread,
Jun 20, 2008, 4:35:22 AM6/20/08
to
Just wondering how the best way to acheive a reverse cat (tac) would
be? I suppose you could do a get-content on a text-file and then
pipe the results into a temporary buffer and then echo them back out
from the bottom up, but it would be nicer if the operation could
tackle large files without having to parse the entire file first. Is
it possible to set the file-pointer to the end and then work up - or
would it be necessary to write some .NET code and then call it on the
fly with the compiler services trick?

Many thanks,

Duncan

Shay Levi

unread,
Jun 20, 2008, 8:37:07 AM6/20/08
to

Hi Duncan,

I'm not sure you can do it without reading the whole file first.
Anyway, the following reads a file and then reverse its content:


function tac($file){ $f= @(cat $file); $f[($f.length-1)..0] }


---
Shay Levi
$cript Fanatic
http://scriptolog.blogspot.com

Duncan Smith

unread,
Jun 20, 2008, 10:08:56 AM6/20/08
to
On Jun 20, 1:37 pm, Shay Levi <n...@addre.ss> wrote:
> Hi Duncan,
>
> I'm not sure you can do it without reading the whole file first.
> Anyway, the following reads a file and then reverse its content:
>
> function tac($file){ $f= @(cat $file); $f[($f.length-1)..0] }
>

Thanks Shay, I thought that might be the case...

Regards,

Duncan

Keith Hill [MVP]

unread,
Jun 20, 2008, 2:16:16 PM6/20/08
to
"Duncan Smith" <DSmit...@googlemail.com> wrote in message news:3bff0b9a-8d70-4a29...@e53g2000hsa.googlegroups.com...
You can do this pretty easily with .NET:

param

([string]$path)
Set-PSDebug -Strict

$fs = New-Object System.IO.FileStream ((Resolve-Path $path), 'Open', 'Read')
trap { $fs.Close(); break }

$pos = $fs.Length
$sb = New-Object System.Text.StringBuilder
while (--$pos -ge 0) {
    [
void]$fs.Seek($pos, 'Begin')
    $ch = [char]$fs.ReadByte()
    if ($ch -eq "`n" -and $sb.Length -gt 0) {
        $sb.ToString().TrimEnd()
        $sb.Length = 0
    }
    [
void]$sb.Insert(0, [char]$ch)
}
$sb.ToString().TrimEnd()

--
Keith

Keith Hill [MVP]

unread,
Jun 20, 2008, 2:31:41 PM6/20/08
to
BTW this approach won't work very well on Unicode files.
 
--
Keith

Duncan Smith

unread,
Jun 23, 2008, 6:26:36 AM6/23/08
to
On Jun 20, 7:31 pm, "Keith Hill [MVP]"

<r_keith_h...@mailhot.moc_no_spam_I> wrote:
> BTW this approach won't work very well on Unicode files.
>
> --
> Keith
>   "Keith Hill [MVP]" <r_keith_h...@mailhot.moc_no_spam_I> wrote in messagenews:C1959F71-7AF2-453D...@microsoft.com...
>   "Duncan Smith" <DSmith1...@googlemail.com> wrote in messagenews:3bff0b9a-8d70-4a29...@e53g2000hsa.googlegroups.com...

>   > Just wondering how the best way to acheive a reverse cat (tac) would
>   > be?   I suppose you could do a get-content on a text-file and then
>   > pipe the results into a temporary buffer and then echo them back out
>   > from the bottom up, but it would be nicer if the operation could
>   > tackle large files without having to parse the entire file first.  Is
>   > it possible to set the file-pointer to the end and then work up - or
>   > would it be necessary to write some .NET code and then call it on the
>   > fly with the compiler services trick?
>
>   You can do this pretty easily with .NET:
>   param([string]$path)

>   Set-PSDebug -Strict
>
>   $fs = New-Object System.IO.FileStream ((Resolve-Path $path), 'Open', 'Read')
>   trap { $fs.Close(); break }
>
>   $pos = $fs.Length
>   $sb = New-Object System.Text.StringBuilder
>   while (--$pos -ge 0) {
>       [void]$fs.Seek($pos, 'Begin')
>       $ch = [char]$fs.ReadByte()
>       if ($ch -eq "`n" -and $sb.Length -gt 0) {
>           $sb.ToString().TrimEnd()
>           $sb.Length = 0
>       }
>       [void]$sb.Insert(0, [char]$ch)
>   }
>   $sb.ToString().TrimEnd()
>
>   --
>   Keith

Thanks Keith, that works well.

Duncan

Hal Rottenberg

unread,
Jun 26, 2008, 8:23:15 AM6/26/08
to
Keith Hill [MVP] wrote:
> BTW this approach won't work very well on Unicode files.

I'm seeing spaces between every character with some files. Is that b/c they are
unicode?

--
Author, Tech Prosaic blog (http://halr9000.com)
Webmaster, Psi (http://psi-im.org)
Community Director, PowerShellCommunity.org
Co-host, PowerScripting Podcast (http://powerscripting.net)

0 new messages