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

Simple scripts in WSH and PowerShell make the last lines first for easy viewing
RSS
View this exclusive article with VIP access -- click here to join | See More COM and COM+ Articles Here | Reprints
Or sign up for our VIP Monthly Pass!
SideBar    Which .NET Classes Can Be Used from Scripts?

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.




Learning Path For help in using batch parameters
"Command-line reference A-Z"

"Shell Scripting 101, Lesson 3"


For more information about the Stack class
"Stack Class"


Further explanation of shadow scripts
"It's the little things …"


Top Viewed ArticlesView all articles
The Memory-Optimization Hoax

Don't believe the hype. At best, RAM optimizers have no effect. At worst, they seriously degrade performance. ...

Managing Virtual Sprawl

As some wise person once said, nothing is ever truly free. Such is the case with VMs, which can quickly mutate from a cost-reducing Dr. Jekyll into a time-consuming, profligate nightmare that would do Mr. Hyde proud. ...

What service packs and fixes are available?

...


Related Articles New .chm File and Task-Based Guide Can Be Helpful PowerShell Resources

PowerShell Resources

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.


ADS BY GOOGLE SPONSORED LINKS FEATURED LINKS

Critical Challenges of ESI & Email Retention
Are you storing too much electronic information? Get expert legal advice and better understanding of what you are required to do as an IT professional.

Become a fan of Windows IT Pro on Facebook!
Join us on Facebook and be a fan of Windows IT Pro!

Sustainable Compliance: Are You Having a Resource Crisis?
Read this white paper to examine trends in compliance and security management and review approaches to reducing the cost and operational burden of compliance.

Rev Up Your IT Know-How with Our Recharged Magazine!
The improved Windows IT Pro provides trusted IT content with an enhanced new look and functionality! Get comprehensive coverage of industry topics, expert advice, and real-world solutions—PLUS access to over 10,000 articles online. Order today!

Get It All with Windows IT Pro VIP
Stock your IT toolbox with every solution ever printed in Windows IT Pro and SQL Server Magazine plus bonus Web-exclusive content on hot topics. Subscribe to receive the VIP CD and a subscription to your choice of Windows IT Pro or SQL Server Magazine!



Order Your Fundamentals CD Today!
Gain an introduction to Exchange, learn server security requirements, and understand how unified communications can play a role in your messaging strategies with this free Exchange CD.
Windows IT Pro Home Register About Us Affiliates / Licensing Media Kit Contact Us/Customer Service  
SQL Connected Home IT Library SuperSite FAQ Wininfo News
Europe Edition Office & SharePoint Pro Windows Dev Pro Windows Excavator 
 
 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