Friday Fun Create Numbered File

I was working on my guest commentary for the upcoming Scripting Games and started thinking I would need a line numbered version of my solution to help explain. Turns out I didn’t go down that road, but in the process I put together a little PowerShell to take a text file and create a line numbered version.

When you are editing a file in the ISE or a script editor like PrimalScript, line numbers help you quickly jump to trouble spots with parsing errors. I decided it would be equally helpful to create a line numbered version of a script. Here’s what I came up with, appropriately numbered.

[cc lang="PowerShell"]
1 #Requires -version 2.0
2
3 # —————————————————————————–
4 # Script: ConvertTo-NumberedText.ps1
5 # Version: 1.0
6 # Author: Jeffery Hicks
7 # http://jdhitsolutions.com/blog
8 # http://twitter.com/JeffHicks
9 # Date: 3/22/2011
10 # Keywords:
11 # Comments:
12 #
13 # “Those who forget to script are doomed to repeat their work.”
14 #
15 # ****************************************************************
16 # * DO NOT USE IN A PRODUCTION ENVIRONMENT UNTIL YOU HAVE TESTED *
17 # * THOROUGHLY IN A LAB ENVIRONMENT. USE AT YOUR OWN RISK. IF *
18 # * YOU DO NOT UNDERSTAND WHAT THIS SCRIPT DOES OR HOW IT WORKS, *
19 # * DO NOT USE IT OUTSIDE OF A SECURE, TEST SETTING. *
20 # ****************************************************************
21 # —————————————————————————–
22
23 $File=Read-Host “Enter the name of the file to convert to numbered output”
24 $Output=Read-Host “Enter the name of the output file”
25
26 if (Test-Path -Path $file)
27 {
28 #read in the total contents of the file
29 $Content=get-content -Path $file
30
31 #get the total number of lines
32 $count=$content.Count
33
34 #convert the count to a string so we can find how many digits. This will
35 #be the padding value
36 $Pad=$count.ToString().Length
37
38 #initialize a counter
39 $i=1
40
41 #pipe the content to ForEach, building a new numbered line and pipe the results to a new
42 #file. The new lines are then piped to Out-File.
43 $content | foreach {
44 #use the -f operaton to construct a string with a padded line number
45 #and the line.
46 “{0} {1}” -f $i.ToString().PadLeft($pad),$_
47
48 #increment the counter
49 $i++
50 } | Out-File -FilePath $Output
51
52 Write-Host “Open $Output for numbered content.” -ForegroundColor Green
53 } #if
54 else
55 {
56 Write-Warning “Can’t find or verify $file.”
57 }
[/cc]

I decided to keep things really simple and prompt the user in lines 23/24 for the script to convert and the new file name.

Line 26 is a quick test to verify the source file exits. If it does, then the entire contents are saved to a variable (line 29). Now the fun part.

I wanted the line numbers to be justified like they are in the ISE. If my script has 134 lines then the first 9 lines needed to be indented 2 spaces and lines 10-99 indented 1. Assuming the script has more than 1 line (otherwise why are you bothering with this?), I get the total line count in line 32.

To determine how much padding I’ll need, I’ll convert this number to a string and get its length (line 36). Armed with this value, I can now go through each line of content (line 43) and construct a new line using the -f operator (line 46). The value of the first placeholder will be the counter value (starting at 1 (line 39)), converted to a string and then padded the necessary number of spaces. The second element is the original line from the imported content.

All that remains is to send the output to the new file in line 50. The main section of the script ends with a message in line 52.

I doubt you’ll need this often but if nothing else it offers a few lessons in the string object and the -f operator.

Download ConvertTo-NumberedText.