Windows IT Pro is the authoritative and independent resource for windows nt, windows 2000, windows 2003, windows xp. Features a collection of resources and magazines for windows IT professionals.
  
  
  Advanced Search 


March 05, 2008

Reversing Lines in a File

RSS
Subscribe to Windows IT Pro | See More COM and COM+ Articles Here | Reprints | Or get the Monthly Online Pass—only $5.95 a month!

Download the Code Here

 Executive Summary:
To see what happened most recently first in text-based logs, you can use the Microsoft .NET Framework's class in both Windows Script Host (WSH) and PowerShell to create a simple reversal script.

I occasionally need to reverse the order of the lines in a text file. Reversal lets me see what happened most recently first in logs, and I can even use it to roll back complex changes such as extended file copy and move operations. No tool does this exact job in Windows, but you can use the Microsoft .NET Framework's Stack class in the System.Collections namespace to make your own tool. I'll demonstrate how to use the Stack class for reversal in both Windows Script Host (WSH) and PowerShell; when I'm done, you'll have tools usable in both the cmd.exe and PowerShell console environments.

The Need for LIFO
Let's talk about the way we typically see files and why reversing the order of their lines might be useful. Due to the way files are stored, we typically understand them as streams of data. The first item into the stream is the first out of the stream; the last item put into a stream is always at the tail end of the stream. This first-in, first-out (FIFO) processing model is called a queue. FIFO is the standard way that data is handled in most simple contexts such as reading, writing, and appending to files from a script.

Although the model works well for problems ranging from recording actions in order of occurrence to processing orders in a supermarket checkout line, sometimes you need to look at the last items first. You might be interested in the most recent lines in the Windows Update log, for example. You also might log complex operations, such as moving and renaming batch files, and might want to reverse what was done—which is possible only if you step through the operations in reverse order. In this last-in, first-out (LIFO) processing, the data structure is called a stack. Just like a stack of papers, the last item you push onto a stack is the first one you can pull (or "pop") from the stack.

Reversing the Stream in VBScript
So to put a file's lines in reverse order, a script simply needs to read the file line by line and stack the lines. The file's first line ends up at the end, and the last line ends up first.

The ReverseStream.vbs script shown in Listing 1 is the simplest possible reversing script. It actually reads from standard input, so you must run it with CScript explicitly as its host. You can put a file into the standard input stream for ReverseStream.vbs in a couple ways. The simplest is to redirect input:

cscript reversestream.vbs < c:\windows\WindowsUpdate.log

Alternatively, you can use the cmd.exe type command to echo the file to the console and then pipe it into the script, like this:

type c:\windows\WindowsUpdate.log | cscript reversestream.vbs

You can save the reversed data by redirecting ReverseStream.vbs's output to a file:

cscript reversestream.vbs < c:\windows\WindowsUpdate.log > wu-reversed.log

To simplify running the script, you can create a file named ReverseStream.cmd in the same folder as ReverseStream.vbs. The ReverseStream.cmd file must contain the line

@cscript //Nologo %~dpn0.vbs %*

You can then just type reversestream instead of cscript reversestream.vbs in commands such as those just shown.

To illustrate what the %~dpn0.vbs expression does, let's look at how it works on my system, where ReverseStream.cmd and ReverseStream.vbs are saved in the C:\apps\bin\scripts folder (which is in my command search path). In a batch file, % followed by a number refers to an element in the command line used to invoke the batch file. The variable %0 means the name used to invoke the batch file. The ~, d, p, and n characters between % and 0 are modifiers. The ~ is supposed to expand the element and remove any surrounding quotes; it also makes the command processor treat any following letters as special modifiers. The d expands to the drive letter for %0, which is C: on my system. The p expands to the relative path for the command, which is \apps\bin\scripts\ on my system. Finally, the n expands to the base name of the command, which is reversestream. So, during runtime, %~dpn0.vbs evaluates to C:, \apps\bin\scripts\, reversestream, and .vbs, forming the expression

c:\apps\bin\scripts\reversestream.vbs

which is the explicit path to the script.

I call ReverseStream.cmd a shadow script, and I discuss this technique a little more in a blog entry that you can link to from the Learning Path. For more information about batch parameters, you can link to the TechNet documentation page listed in the Learning Path.

One other technique that works if you're running the 64-bit version of cmd.exe is to set the default WSH host to CScript by using the command

cscript //h:cscript

This technique won't work if you're running the 32-bit version of cmd.exe. A longstanding flaw of the 32-bit command processor is that it breaks the input pipeline for scripts hosted in external applications such as WSH and Perl.

Inner Workings
Let's step through how the script works. For your reference, Table 1 includes some of the significant properties and methods of the .NET System.Collections.Stack class. I use only a couple of these, but the others are handy to know about if you use a stack in other situations.

In the ReverseStream.vbs script in Listing 1, the code at callout A simply creates a System.Collections.Stack object. Even though Stack is a .NET class, it's visible to COM scripting by name. A subset of .NET classes is available for scripting. The "Which .NET Classes Can Be Used from Scripts?" sidebar outlines rules of thumb for administrators to use in finding COM-usable .NET classes and methods.

The next step is to stack the items. At callout B in Listing 1, the script reads lines as long as input is available, and pushes each line onto the stack. I could have used the Pop() method to pop items off the stack until the stack is empty. If I had used that approach, it would look like this:

Do While Stack.Count > 0
  WScript.StdOut.WriteLine Stack.Pop
Loop

However, there's a shortcut. The script can put the stack into an array using ToArray and then join the items by using line endings—which is what the script does at callout C in Listing 1. This approach not only uses shorter code but also reduces the time and processing required for larger stacks.

The PowerShell Version
The PowerShell version of ReverseStream.vbs, Reverse-Stream.ps1 in Listing 2, works similarly. You can use it in any PowerShell pipeline to reverse the items fed to it. You use the Get-Content cmdlet to get the contents of a file:

get-content c:\windows\WindowsUpdate.log | reverse-stream

In this statement, you can use gc or type instead of get-content because gc and type are built-in aliases for the Get-Content cmdlet.

The code for the Reverse-Stream.ps1 script is analogous to the VBScript version but even simpler. Note that if you don't have the Reverse-Stream.ps1 script saved to a directory in your Windows search path, you'll need to specify the full path to the script instead of just its name.

The begin clause (which always runs when a script starts up) creates the stack object $stack. Each time an object is read from the input stream, the process clause runs and the object is passed in as $_. All the process clause does is push the object onto the stack.

After the script reaches the end of the input, the end code runs. The script doesn't need to bother with popping the stacked items off the stack or putting them into an array. PowerShell recognizes .NET collections like the Stack object and takes care of it for us. All the script needs to do is push $stack out, and the breakdown is automatically displayed.

End of Article



Reader Comments

You must log on before posting a comment.

If you don't have a username & password, please register now.




Top Viewed ArticlesView all articles
WinInfo Short Takes: Week of September 8, 2008

An often irreverent look at some of the week's other news, including the long-awaited back to school season, Microsoft's first Seinfeld/Gates ad, some EU insights, another Netbook improvement, Opera silliness, and much, much more ...

VMware and the Future of Virtualization

What's next for virtualization and business IT? Windows IT Pro senior editor Jeff James speaks with VMware President and CEO Diane Greene on the future of virtualization technology. ...

IE 8.0 and Chrome Could Enable Next-Gen Web Apps—Unless Your ISP's Bandwidth Cap Gets in the Way

Both browsers are being positioned as the core system application that will enable the next generation of web apps--however, ISP usage caps could throw a major monkey wrench at web-based application delivery. ...


Related Events Check out our list of Free Email Newsletters!

Scripting eBooks Keeping Your Business Safe from Attack: Encryption and Certificate Services

Best Practices for Managing Linux and UNIX Servers

Building an Effective Reporting System

Related Scripting Resources Become a VIP member of the Windows IT Pro community!
Get it all with the VIP CD and VIP access. A $500+ value for only $279!

Subscribe to Windows IT Pro!
Solve your toughest technical problems with our experts and access 10,000 + articles online. 30% off

Monthly Online Pass - Only $5.95!
Get instant access to 10,000+ articles from Windows IT Pro Magazine!

TechNet Virtual Labs
Evaluate and test Microsoft's newest products.

Job Openings in IT


ADS BY GOOGLE SPONSORED LINKS FEATURED LINKS

IT Connections
Dive into the new Microsoft platforms and products you implement and support with the experts from Microsoft, TechNet Magazine, Windows ITPro and industry gurus. There are 70+ sessions and interactive panels with networking opportunities.

Attention User Group Leaders...
Announcing the eNews Generator—a FREE HTML e-newsletter builder for user group leaders. Build your HTML and text e-newsletters in minutes and add Windows IT Pro & SQL Server Mag articles alongside your own message!.

Master SharePoint with 3 eLearning Seminars
Learn how to build a better SharePoint infrastructure and enable powerful collaboration with MVPs Dan Holme and Michael Noel. Register today!

Get SQL Server 2008 at WinConnections
Don’t miss Microsoft Exchange and Windows Connections conferences, the premier events for Microsoft IT Professionals in Las Vegas, November 10-13. Every attendee will receive a copy of SQL Server 2008 Standard Edition with one CAL.



Interested in Email Encryption?
Read about the advantages of identity-based encryption in this free report.

Order Your SQL Fundamentals CD Today!
Learn how to use SQL Server, understand Office integration techniques and dive into the essentials of SQL Express and Visual Basic with this free SQL Fundamentals CD.

Virtualization Congress Oct. 14-16 in London
Don't miss Virtualization Congress, the premiere EMEA conference dedicated to hardware, OS and application virtualization. Oct. 14-16.
Windows IT Pro Home Register FAQ for Windows WinInfo News
Europe Edition About Us Contact Us/Customer Service Media Kit Affiliates / Licensing  
SQL Server Magazine Office & SharePoint Pro Windows Dev Pro IT Job Hound ITTV
IT Library Technical Resources Directory Connected Home Windows Excavator Windows SuperSite 
 
 Windows IT Pro is a Division of Penton Media Inc.
 Copyright © 2008 Penton Media, Inc., All rights reserved. Terms and Use | Privacy Statement | Reprints and Licensing