locked
Casting changes between PowerShell 2.0 and 3.0 RRS feed

  • Question

  • I've just noticed that a script I wrote a very long time ago is not working as expected. The script sorts a list of files in a directory. The files are named both with IP addresses and with sequential number. For example:

    PS C:\> $tmp
    10.0.144.0-1.png
    10.0.144.0-3.png
    10.0.144.0-2.png
    10.0.144.0-4.png
    10.0.16.0-1.png
    10.0.16.0-3.png
    10.0.16.0-2.png
    10.0.16.0-4.png
    10.0.160.0-1.png
    10.0.160.0-3.png
    10.0.160.0-2.png
    10.0.160.0-4.png

    I want this sorted, so in PowerShell 2.0 I do this:

    PS C:\> powershell.exe -version 2
    Windows PowerShell
    Copyright (C) 2009 Microsoft Corporation. All rights reserved.
    
    
    PS C:\> $tmp = @("10.0.144.0-1.png",
    >> "10.0.144.0-3.png",
    >> "10.0.144.0-2.png",
    >> "10.0.144.0-4.png",
    >> "10.0.16.0-1.png",
    >> "10.0.16.0-3.png",
    >> "10.0.16.0-2.png",
    >> "10.0.16.0-4.png",
    >> "10.0.160.0-1.png",
    >> "10.0.160.0-3.png",
    >> "10.0.160.0-2.png",
    >> "10.0.160.0-4.png")
    >>
    PS C:\> $tmp|sort -Property @{Expression={"{0:d3}.{1:d3}.{2:d3}.{3:d1}-{4:d1}" -f @([int[]]$($_).split('.|-')[0..4])}}
    10.0.16.0-1.png
    10.0.16.0-2.png
    10.0.16.0-3.png
    10.0.16.0-4.png
    10.0.144.0-1.png
    10.0.144.0-2.png
    10.0.144.0-3.png
    10.0.144.0-4.png
    10.0.160.0-1.png
    10.0.160.0-2.png
    10.0.160.0-3.png
    10.0.160.0-4.png
    PS C:\> exit


    The expression in the sort command splits the file name string and takes the first five elements of the resulting array, converted to integers, and pads them with extra digits so that sort will see each octet as three digits. That is, if I omit the sort and just output the content as formatted by the expression:

    PS C:\> $tmp|%{"{0:d3}.{1:d3}.{2:d3}.{3:d3}-{4:d1}" -f @([int[]]$($_).split('.|-')[0..4])}
    010.000.144.000-1
    010.000.144.000-3
    010.000.144.000-2
    010.000.144.000-4
    010.000.016.000-1
    010.000.016.000-3
    010.000.016.000-2
    010.000.016.000-4
    010.000.160.000-1
    010.000.160.000-3
    010.000.160.000-2
    010.000.160.000-4

    However, when I try to do the same thing in PowerShell 3.0 or later, it all goes wrong:

    PS C:\> $tmp|%{"{0:d3}.{1:d3}.{2:d3}.{3:d3}-{4:d1}" -f @([int[]]$($_).split('.|-')[0..4])}
    Error formatting a string: Index (zero based) must be greater than or equal to zero and less than the size of the argument list..
    At line:1 char:59
    + $tmp|%{"{0:d3}.{1:d3}.{2:d3}.{3:d3}-{4:d1}" -f @([int[]]$($_).split(' ...
    +                                                           ~~
        + CategoryInfo          : InvalidOperation: ({0:d3}.{1:d3}.{2:d3}.{3:d3}-{4:d1}:String) [], RuntimeException
        + FullyQualifiedErrorId : FormatError

    Error formatting a string: Index (zero based) must be greater than or equal to zero and less than the size of the argument list..
    At line:1 char:59
    + $tmp|%{"{0:d3}.{1:d3}.{2:d3}.{3:d3}-{4:d1}" -f @([int[]]$($_).split(' ...
    +                                                           ~~
        + CategoryInfo          : InvalidOperation: ({0:d3}.{1:d3}.{2:d3}.{3:d3}-{4:d1}:String) [], RuntimeException
        + FullyQualifiedErrorId : FormatError

    .

    .

    .


    Apparently the cast to INT isn't working any more and obviously if I try to sort it fails miserably.

    Anyone aware of what changed and how I might fix this?





    • Edited by Neil Fairall Friday, January 26, 2018 3:07 PM Remove some PII
    Friday, January 26, 2018 2:59 PM

Answers

  • Hmm, I am not entirely sure how that syntax worked in the first place, but I thought about it a bit and decided to just change the expression. I think this does the trick although it looks kind of messy:

    PS C:\> $tmp|sort-object -Property @{Expression={"{0:d3}.{1:d3}.{2:d3}.{3:d3}-{4:d1}" -f ($_.split('.|-')[0..4]|%{[int]$_})}}
    10.0.16.0-1.png
    10.0.16.0-2.png
    10.0.16.0-3.png
    10.0.16.0-4.png
    10.0.144.0-1.png
    10.0.144.0-2.png
    10.0.144.0-3.png
    10.0.144.0-4.png
    10.0.160.0-1.png
    10.0.160.0-2.png
    10.0.160.0-3.png
    10.0.160.0-4.png


    • Marked as answer by Neil Fairall Saturday, January 27, 2018 2:19 AM
    Friday, January 26, 2018 5:20 PM