Formatting Strings In PowerShell Using Fixed Width Columns
Working with strings in PowerShell is fun, I don’t care what you say. In this post, I’m going to show you how to clean up the strings your code outputs, at least in some situations.
Say you have a variable $fileExtensions which you populated with this command.
PS> $fileExtensions = Get-ChildItem | Group-Object -Property Extension
And, for some reason, instead of the default output which is formatted like a table, I want output presented like this.
.ps1 file extension: 11
.xlsx file extension: 3
.dll file extension: 1
This is a silly example, but notice that even though there are extensions of varying length (.ps1 and .dll are four characters including the dot, and .xlsx is five), all of the “file extension: <number>” is aligned.
How’d I do that? Let’s start with some code that doesn’t work.
PS> $fileExtensions | foreach-object { "$($_.Name) file extension: $($_.Count)" }
.ps1 file extension: 11
.xlsx file extension: 3
.dll file extension: 3
How incredibly unfortunately unattractive! Luckily, it’s not too hard to fix. Check out this code.
PS> $fileExtensions | foreach-object { "{0,-8} file extension: {1}" -f $_.Name, $_.Count }
.ps1 file extension: 11
.xlsx file extension: 3
.dll file extension: 3
Oh yes look at that goodness. In this example I’m using the -f operator to insert the variables into the string. Let’s break down the new string I’m creating.
{0} and {1] are basically placeholders. The -f operator is going to insert the variables that come after it ($_.Name and $_.Count) into the 0 and 1 spots.
The ,-8 is a formatting instruction. The 8 means that this part of the string is going to be a column that takes up 8 characters worth of space. The negative sign means that the data inserted is left aligned. If I had used “positive eight” it would have been right aligned.
Now you can take this and run, to do fun things like this.
# Input
$header = "[$(Get-Date -format G)]"
Write-Output "$header First line"
Write-Output $("{0,$($header.Length)} Second line" -f " ")
Write-Output $("{0,$($header.Length)} Third line" -f " ")
# Output
[11/2/2017 12:47:58 PM] First line
Second line
Third line