Heine Kristensen
Heine Kristensen

Reputation: 93

Powershell sort from line 2

I want to sort a .txt document, so that the first line stays on top, and the rest gets sorted by numbers.

I currently have the following, but it removes the first line, and the sorting isn't correct, since the numbers are e.g. 72, 2, 51, 100, 201, 5 etc. so it sorts it like 100, 2, 201, 5, 51, 72.

And I wish to have it sorted like 2, 5, 51, 72, 100, 201

$emptyLine = Get-Content C:\Path\Document.txt | Select-Object -Skip 1
$emptyLine | Sort-Object | Out-File C:\Path\Document.txt

I know this is possible in Notepad++ but the machine that needs to do the sorting isn't allowed to install anything new.

I'm very open if for any solution, that doesn't require me to install a new piece of software.

The machine is Windows 10 Pro x64.

Current Picture

Desired result

Current Result

No        Tool_Name        Tool_Part
72        10        1      9.	   1
43        36        3      29.     1
102       34        1      1.7     1
600       33        1      3.      1
76        3         1      5.3     1
75        3         1      5.5     1
251       2         3      3.      1
73        10        1      5.3     1
50        36        3      15.9    1
64        2         1      6.      1

(Posted as HTML snippet, to make formatting more beautiful)

Upvotes: 1

Views: 842

Answers (2)

Mathias R. Jessen
Mathias R. Jessen

Reputation: 174515

Take advantage of multi-value assignment and store the output from Get-Content in two variables, then sort only the second:

$First,$Rest = Get-Content C:\Path\Document.txt
@($First; $Rest |Sort-Object) |Set-Content C:\Path\Document.txt

In the scenario above, PowerShell will assign the first line to $First and the rest to $Rest

If you need Sort-Object to sort by the first part of a string property as if it was an integer, you could do it like this:

@($First; $Rest |Sort-Object {(-split $_)[0] -as [int]}) |Set-Content C:\Path\Document.txt

Upvotes: 6

iRon
iRon

Reputation: 23663

You might use Get-Content, skip the header and than do some tricks to rebuild your table but you might also consider using the ConvertFrom-SourceTable from the PowerShell Gallery to convert your table directly into objects:

$List = Get-Content C:\Path\Document.txt | ConvertFrom-SourceTable

Unfortunately the numbers in the first column appear to be left aligned, if they where right aligned (as in the final results of this answer), the ConvertFrom-SourceTable cmdlet would have automatically evaluated the first 'No' column into numbers.
This means that you will need to transfer the first column into integers yourself to be able to sort them as suggested. You can do this by using the Select-Object and creating a calculated property:

Select-Object @{n='No'; e={[Int]$_.No}}, Tool_Name, Tool_Part

After that, you can simply use sort-Object to sort it:

Sort-Object No

Putting an example together:

ConvertFrom-SourceTable '
    No        Tool_Name        Tool_Part
    72        10        1      9.      1
    43        36        3      29.     1
    102       34        1      1.7     1
    600       33        1      3.      1
    76        3         1      5.3     1
    75        3         1      5.5     1
    251       2         3      3.      1
    73        10        1      5.3     1
    50        36        3      15.9    1
    64        2         1      6.      1
' | Select-Object @{n='No'; e={[Int]$_.No}}, Tool_Name, Tool_Part | Sort-Object No

This example will result in:

 No Tool_Name Tool_Part
 -- --------- ---------
 43 36        29.     1
 50 36        15.9    1
 64 2         6.      1
 72 10        9.      1
 73 10        5.3     1
 75 3         5.5     1
 76 3         5.3     1
102 34        1.7     1
251 2         3.      1
600 33        3.      1

As it is unclear whether the column between Tool_Name and Tool_Part belongs to either of the column (because Tool_Part could be either left aligned or right aligned), you might provide a ruler to the ConvertFrom-SourceTable yourself to settle this:

ConvertFrom-SourceTable -Ruler '---       -----------      ---------' '
No        Tool_Name        Tool_Part
72        10        1      9.      1
43        36        3      29.     1
102       34        1      1.7     1
600       33        1      3.      1
76        3         1      5.3     1
75        3         1      5.5     1
251       2         3      3.      1
73        10        1      5.3     1
50        36        3      15.9    1
64        2         1      6.      1
' | Select-Object @{n='No'; e={[Int]$_.No}}, Tool_Name, Tool_Part | Sort-Object No

Result:

 No Tool_Name   Tool_Part
 -- ---------   ---------
 43 36        3 29.     1
 50 36        3 15.9    1
 64 2         1 6.      1
 72 10        1 9.      1
 73 10        1 5.3     1
 75 3         1 5.5     1
 76 3         1 5.3     1
102 34        1 1.7     1
251 2         3 3.      1
600 33        1 3.      1

Upvotes: 2

Related Questions