Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PowerShell Sort-Order Incorrect

So I'm trying to use PowerShell to sort C# "using" statements at the top of a file. For the given input file File.cs, the using statements look like this:

using System.Reflection;
using System.Configuration;
using System.Runtime.Caching;
using System.Linq;
using System;

I expect the output have "using System" as the first "using", but actually Sort-Object sorts it to the bottom. How can I change this to sort to the top of the list?

function Update-UsingStatements
{
  param (
    [Parameter(Mandatory=$true)][string]$FilePath
  )

  $fileLines = Get-Content $FilePath
  $contents = $fileLines | Out-String

  $list = New-Object 'System.Collections.Generic.List[string]'
  $contents | Select-String -pattern 'using\s[\w\.]+;' -AllMatches | ForEach-Object {$_.Matches} | ForEach-Object { $list.Add($_.Value) }
  $list = $list | Sort-Object

  for ($i = 0; $i -lt $list.Count; $i++)
  {
    $fileLines[$i] = $list[$i]
  }

  $fileLines | Out-File $FilePath -Encoding utf8
}
like image 743
Andy Avatar asked Feb 04 '23 11:02

Andy


2 Answers

You're getting that sort order because the strings include the trailing ;, and in the character table ; (ASCII character 59) comes after . (ASCII character 46). So the sort order is absolutely correct, even if it's not what you expected.

Remove the trailing semicolon from the property by which you sort to remedy that:

$list = $list | Sort-Object { $_ -replace ';' }
like image 82
Ansgar Wiechers Avatar answered Feb 08 '23 16:02

Ansgar Wiechers


Using Ansgar Wiechers' sort adjustment as the main fix, you can get rid of a lot of ye olde worlde counting contortions in the rest of the code:

function Update-UsingStatements
{
  param (
    [Parameter(Mandatory=$true)][string]$FilePath
  )

  # Separate the 'using' statements from everything else
  $using, $rest = (Get-Content -Path $FilePath).where({$_ -match '^using '}, 'split')

  # sort the 'using' statements, with a tweak to bring 'using system;' to the top
  $using = $using | Sort-Object -Property { $_ -replace ';' }

  # output sorted 'using' statements and rest of file, over the original file
  $using, $rest | Set-Content -Path $FilePath -Encoding UTF8

}
like image 32
TessellatingHeckler Avatar answered Feb 08 '23 15:02

TessellatingHeckler