Reputation: 93
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.
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
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
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