2

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. :)

4
  • I'm not sure what the issue is then. I took the code you posted and ran it and got a sorted result.
    – EBGreen
    Apr 24, 2012 at 15:04
  • Thanks for the help @EBGreen. Though I'm not sure what to do accept your answer or write an answer for my own question, because you helped me a lot, and I think you deserve the reputation.
    – szantaii
    Apr 24, 2012 at 16:56
  • meh, I'm not worried about the rep. My prefference would be for you to do a nice write up of the solution, the whys and wherefores.
    – EBGreen
    Apr 24, 2012 at 17:33
  • Okay, I'm going to do that then.
    – szantaii
    Apr 25, 2012 at 7:43

1 Answer 1

2

Try something like this:

Import-CSV C:\Path\To\File.txt -Header ('foo', 'bar', 'wombat') -delimiter ' ' | Sort-Object wombat

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:

$allfiles=get-childitem $inputpath -rec | Where-Object {!($_.psiscontainer)} | Sort-Object Name
cd $inputpath
foreach ($file in $allfiles) {cksum.exe $file | Out-File -Append $pathtooutputfile}
5
  • Thanks. This almost works but file names and directory names that contain space characters messes up the thing.
    – szantaii
    Apr 24, 2012 at 13:38
  • Then you don't have proper columns.
    – EBGreen
    Apr 24, 2012 at 13:39
  • How exactly are you generating the text file?
    – EBGreen
    Apr 24, 2012 at 13:49
  • Actually I use cksum: $allfiles=get-childitem $inputpath -rec | Where-Object {!($_.psiscontainer)} cd $inputpath foreach ($file in $allfiles) {cksum.exe $file | Out-File -Append $pathtooutputfile}
    – szantaii
    Apr 24, 2012 at 13:58
  • Thanks for the edit, but that's what I've been using. I've edited the question, and added some more code. Anyhow, thanks.
    – szantaii
    Apr 24, 2012 at 14:56

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .