I've a text file like this:
4108689096 2531 ./ssss/132432.odt
481446057 2293 ./abc/a.txt
3157353085 1096 ./dsjvbjf/c.docx
653380669 1824 ./bcd/x.avi
And I'd like to achieve in Powershell to sort the list by the third column, but Sort-Object
seems to sort this list by the file name (by the first character after the last /
in every row) whatever I do.
I'd like to achieve something like this:
481446057 2293 ./abc/a.txt
653380669 1824 ./bcd/x.avi
3157353085 1096 ./dsjvbjf/c.docx
4108689096 2531 ./ssss/132432.odt
So I'd like to sort by the third column as a string including .
, /
characters.
Edit #1: Some relevant code
# Gets a relative path based on a base and a full path (to file)
#
# Usage: RelativePath <path to file> <base path>
#
# Note: Specifying arguments is mandatory.
function global:RelativePath
{
param
(
[string]$path = $(throw "Missing: path"),
[string]$basepath = $(throw "Missing: base path")
)
return [system.io.path]::GetFullPath($path).SubString([system.io.path]::GetFullPath($basepath).Length + 1)
}
# Calculates CRC checksums for all files in the specified directory and writes
# the checksums to a file
#
# Usage: CRCSumAll <path to folder to check> <file conatining checksums>
#
# Note: Specifying arguments is mandatory.
function global:CRCSumAll
{
param($inputpath,$outputfile)
$allfiles=get-childitem $inputpath -rec | Where-Object {!($_.psiscontainer)} | Sort-Object Name
new-item -force -type file $outputfile
cd $inputpath
foreach ($file in $allfiles)
{
$relfile=RelativePath $file.fullname $inputpath
$relfile=$relfile -replace("\\","/")
$relfile="./$relfile"
cksum.exe $relfile | Out-File -Encoding OEM -Append $outputfile
}
}
Edit #2: Solution
I realized what was the problem. I added the relative paths after sorting. So the correct code is:
function global:CRCSumAll
{
param($inputpath,$outputfile)
$allfiles=get-childitem $inputpath -rec | Where-Object {!($_.psiscontainer)} #| Sort-Object Name
new-item -force -type file $outputfile
cd $inputpath
foreach ($file in $allfiles)
{
$relfile=RelativePath $file.fullname $inputpath
$relfile=$relfile -replace("\\","/")
$relfile="./$relfile"
$relfile | Out-File -Encoding OEM -Append $outputfile
}
$sorted=Get-Content $outputfile | Sort-Object
new-item -force -type file $outputfile
$sorted | Out-File -Encoding OEM -Append $outputfile
$forcksum=Get-Content $outputfile
new-item -force -type file $outputfile
$forcksum | Foreach-Object { cksum.exe $_ | Out-File -Encoding OEM -Append $outputfile}
}
Now I only have to clean up the code a little bit, because writing a file three times is really ugly. 🙂
Best Answer
Try something like this:
I'll leave my original answer since it meets the criteria as long as the input has well defined columns. Based on the comments, the solution is to sort the array at creation: