Windows Vista Forums

IP Addresses sort with Powershell
  1. #1


    Martin Brill Guest

    IP Addresses sort with Powershell

    Hi,

    i wrote a Linux AWK Script, which sorts IP-Addresses.

    >>>

    #> cat ips | awk -F. '{printf("%03d.%03d.%03d.%03d\n", $1,$2,$3,$4)};' |
    sort -n -t "." | awk -F. '{printf("%d.%d.%d.%d\n", $1,$2,$3,$4)};'
    <<<

    The Windows Powershell is new for me. How can I make this with the Windows
    Powershell?

    My try:

    >>>

    PS C:\Users\Martin> get-content ips
    124.5.6.8
    2.4.53.233
    12.24.3.78
    234.2.5.7
    1.5.5.5

    PS C:\Users\Martin> get-content ips | sort-object

    1.5.5.5
    12.24.3.78
    124.5.6.8
    2.4.53.233
    234.2.5.7
    PS C:\Users\Martin>
    <<<

    This result is not correct, i need this result:

    1.5.5.5
    2.4.53.233
    12.24.3.78
    124.5.6.8
    234.2.5.7

    Thank you.



    Best regards
    Martin


      My System SpecsSystem Spec

  2. #2


    Keith Hill [MVP] Guest

    Re: IP Addresses sort with Powershell

    "Martin Brill" <martin_brill-ns@msn.com> wrote in message news:%23Hfs0WbtHHA.3796@TK2MSFTNGP02.phx.gbl...
    > Hi,
    >
    > i wrote a Linux AWK Script, which sorts IP-Addresses.
    >
    >>>>

    > #> cat ips | awk -F. '{printf("%03d.%03d.%03d.%03d\n", $1,$2,$3,$4)};' |
    > sort -n -t "." | awk -F. '{printf("%d.%d.%d.%d\n", $1,$2,$3,$4)};'
    > <<<
    >
    > The Windows Powershell is new for me. How can I make this with the Windows
    > Powershell?


    Use the force, er I mean objects. :-)

    78> gc ips.txt | %{[Net.IPAddress]::Parse($_)} | sort Address | ft IPAddressToString

    IPAddressToString
    -----------------
    1.5.5.5
    234.2.5.7
    124.5.6.8
    12.24.3.78
    2.4.53.233

    --
    Keith


      My System SpecsSystem Spec

  3. #3


    Martin Brill Guest

    Re: IP Addresses sort with Powershell

    Hi Keith,

    >>>

    78> gc ips.txt | %{[Net.IPAddress]::Parse($_)} | sort Address | ft
    IPAddressToString

    IPAddressToString
    -----------------
    1.5.5.5
    234.2.5.7
    124.5.6.8
    12.24.3.78
    2.4.53.233
    <<<

    Thanks, but this is not the correct result, i need the correct IP Sequence

    1.5.5.5
    2.4.53.233
    12.24.3.78
    124.5.6.8
    234.2.5.7

    --

    Best Regards
    Martin


      My System SpecsSystem Spec

  4. #4


    Keith Hill [MVP] Guest

    Re: IP Addresses sort with Powershell

    OK don't I feel like a complete a$$. Doh! That's what I get for not having put in my contacts. Too bad though, this would have worked if it weren't for the fact that network byte order is different from the Intel byte order (big vs little endian). We can correct that but it is uglier:

    85> gc ips.txt | %{[System.Net.IPAddress]::Parse($_)} | sort {$bytes=$_.GetAddressBytes();[array]::Reverse($bytes);[BitConverter]::ToUInt32($bytes,0)} | ft IPAddressToString

    IPAddressToString
    -----------------
    1.5.5.5
    2.4.53.233
    12.24.3.78
    124.5.6.8
    234.2.5.7

    If you did this a lot I would consider modifying the type data for System.Net.IPAddress to add a BegEndianAddress property like so:

    Create an IPAddress.ps1xml file with these contents:

    <?xml version="1.0" encoding="utf-8" ?>
    <Types>
    <Type>
    <Name>System.Net.IPAddress</Name>
    <Members>
    <ScriptProperty>
    <Name>BigEndianAddress</Name>
    <GetScriptBlock>
    $bytes=$this.GetAddressBytes()
    [array]::Reverse($bytes)
    [BitConverter]::ToUInt32($bytes,0)
    </GetScriptBlock>
    </ScriptProperty>
    </Members>
    </Type>
    </Types>

    Now execute:

    2> Update-TypeData IPAddress.ps1xml

    You've just added a new property to every System.Net.IPAddress object that you will encounter in PowerShell. You might want to put the Update-TypeData command in your profile so that this additional type data gets loaded every time you start PowerShell.

    Now try this:

    3> gc ips.txt | %{[System.Net.IPAddress]::Parse($_)} | sort BigEndianAddress | ft IPAddressToString

    IPAddressToString
    -----------------
    1.5.5.5
    2.4.53.233
    12.24.3.78
    124.5.6.8
    234.2.5.7

    Now if I squint hard enough, yes, it does appear that was the order you were looking for. :-)

    --
    Keith

    "Keith Hill [MVP]" <r_keith_hill@mailhot.nospamIdotcom> wrote in message news:%23$zeI4btHHA.2004@TK2MSFTNGP03.phx.gbl...
    "Martin Brill" <martin_brill-ns@msn.com> wrote in message news:%23Hfs0WbtHHA.3796@TK2MSFTNGP02.phx.gbl...
    > Hi,
    >
    > i wrote a Linux AWK Script, which sorts IP-Addresses.
    >
    >>>>

    > #> cat ips | awk -F. '{printf("%03d.%03d.%03d.%03d\n", $1,$2,$3,$4)};' |
    > sort -n -t "." | awk -F. '{printf("%d.%d.%d.%d\n", $1,$2,$3,$4)};'
    > <<<
    >
    > The Windows Powershell is new for me. How can I make this with the Windows
    > Powershell?


    Use the force, er I mean objects. :-)

    78> gc ips.txt | %{[Net.IPAddress]::Parse($_)} | sort Address | ft IPAddressToString

    IPAddressToString
    -----------------
    1.5.5.5
    234.2.5.7
    124.5.6.8
    12.24.3.78
    2.4.53.233

    --
    Keith


      My System SpecsSystem Spec

  5. #5


    Keith Hill [MVP] Guest

    Re: IP Addresses sort with Powershell

    And if you really want to do it lexigraphically:

    132> gc ips.txt | %{"{0:000}.{1:000}.{2:000}.{3:000}" -f @([int[]]$_.split('.'))} |
    sort | %{"{0}.{1}.{2}.{3}" -f @([int[]]$_.split('.'))}
    1.5.5.5
    2.4.53.233
    12.24.3.78
    124.5.6.8
    234.2.5.7

    That's 129 chars to type versus your original comand that was ~120. The primary trick with this approach in powershell is that once you split on '.' you need to convert each part into a number.

    --
    Keith
    "Keith Hill [MVP]" <r_keith_hill@mailhot.nospamIdotcom> wrote in message news:eRM04IctHHA.768@TK2MSFTNGP04.phx.gbl...
    OK don't I feel like a complete a$$. Doh! That's what I get for not having put in my contacts. Too bad though, this would have worked if it weren't for the fact that network byte order is different from the Intel byte order (big vs little endian). We can correct that but it is uglier:

    85> gc ips.txt | %{[System.Net.IPAddress]::Parse($_)} | sort {$bytes=$_.GetAddressBytes();[array]::Reverse($bytes);[BitConverter]::ToUInt32($bytes,0)} | ft IPAddressToString

    IPAddressToString
    -----------------
    1.5.5.5
    2.4.53.233
    12.24.3.78
    124.5.6.8
    234.2.5.7

    If you did this a lot I would consider modifying the type data for System.Net.IPAddress to add a BegEndianAddress property like so:

    Create an IPAddress.ps1xml file with these contents:

    <?xml version="1.0" encoding="utf-8" ?>
    <Types>
    <Type>
    <Name>System.Net.IPAddress</Name>
    <Members>
    <ScriptProperty>
    <Name>BigEndianAddress</Name>
    <GetScriptBlock>
    $bytes=$this.GetAddressBytes()
    [array]::Reverse($bytes)
    [BitConverter]::ToUInt32($bytes,0)
    </GetScriptBlock>
    </ScriptProperty>
    </Members>
    </Type>
    </Types>

    Now execute:

    2> Update-TypeData IPAddress.ps1xml

    You've just added a new property to every System.Net.IPAddress object that you will encounter in PowerShell. You might want to put the Update-TypeData command in your profile so that this additional type data gets loaded every time you start PowerShell.

    Now try this:

    3> gc ips.txt | %{[System.Net.IPAddress]::Parse($_)} | sort BigEndianAddress | ft IPAddressToString

    IPAddressToString
    -----------------
    1.5.5.5
    2.4.53.233
    12.24.3.78
    124.5.6.8
    234.2.5.7

    Now if I squint hard enough, yes, it does appear that was the order you were looking for. :-)

    --
    Keith

      My System SpecsSystem Spec

  6. #6


    Keith Hill [MVP] Guest

    Re: IP Addresses sort with Powershell

    Also turns out that converting the string to an IPAddress object can be shortened to:

    gc ips.txt | %{[net.ipaddress]$_}

    --
    Keith
    "Keith Hill [MVP]" <r_keith_hill@mailhot.nospamIdotcom> wrote in message news:eRM04IctHHA.768@TK2MSFTNGP04.phx.gbl...
    OK don't I feel like a complete a$$. Doh! That's what I get for not having put in my contacts. Too bad though, this would have worked if it weren't for the fact that network byte order is different from the Intel byte order (big vs little endian). We can correct that but it is uglier:

    85> gc ips.txt | %{[System.Net.IPAddress]::Parse($_)} | sort {$bytes=$_.GetAddressBytes();[array]::Reverse($bytes);[BitConverter]::ToUInt32($bytes,0)} | ft IPAddressToString

    IPAddressToString
    -----------------
    1.5.5.5
    2.4.53.233
    12.24.3.78
    124.5.6.8
    234.2.5.7

    If you did this a lot I would consider modifying the type data for System.Net.IPAddress to add a BegEndianAddress property like so:

    Create an IPAddress.ps1xml file with these contents:

    <?xml version="1.0" encoding="utf-8" ?>
    <Types>
    <Type>
    <Name>System.Net.IPAddress</Name>
    <Members>
    <ScriptProperty>
    <Name>BigEndianAddress</Name>
    <GetScriptBlock>
    $bytes=$this.GetAddressBytes()
    [array]::Reverse($bytes)
    [BitConverter]::ToUInt32($bytes,0)
    </GetScriptBlock>
    </ScriptProperty>
    </Members>
    </Type>
    </Types>

    Now execute:

    2> Update-TypeData IPAddress.ps1xml

    You've just added a new property to every System.Net.IPAddress object that you will encounter in PowerShell. You might want to put the Update-TypeData command in your profile so that this additional type data gets loaded every time you start PowerShell.

    Now try this:

    3> gc ips.txt | %{[System.Net.IPAddress]::Parse($_)} | sort BigEndianAddress | ft IPAddressToString

    IPAddressToString
    -----------------
    1.5.5.5
    2.4.53.233
    12.24.3.78
    124.5.6.8
    234.2.5.7

    Now if I squint hard enough, yes, it does appear that was the order you were looking for. :-)

    --
    Keith

      My System SpecsSystem Spec

  7. #7


    Kiron Guest

    Re: IP Addresses sort with Powershell

    Keith,
    Which .Net books would you recommend to an intermediate scripter?

    Your 'lexigraphical' solution could be shorter:

    gc ips.txt | % {"{0}.{1}.{2}.{3}" -f @([int[]]$_.split('.'))} | sort

    Thanks for sharing all the .Net information.

    --
    Kiron

      My System SpecsSystem Spec

  8. #8


    Keith Hill [MVP] Guest

    Re: IP Addresses sort with Powershell

    FYI I captured this as a work item for PowerShell Community Extensions v.next:

    http://www.codeplex.com/PowerShellCX...rkItemId=11295

    --
    Keith

    "Keith Hill [MVP]" <r_keith_hill@mailhot.nospamIdotcom> wrote in message news:eRM04IctHHA.768@TK2MSFTNGP04.phx.gbl...
    If you did this a lot I would consider modifying the type data for System.Net.IPAddress to add a BegEndianAddress property like so:

    Create an IPAddress.ps1xml file with these contents:

    <?xml version="1.0" encoding="utf-8" ?>
    <Types>
    <Type>
    <Name>System.Net.IPAddress</Name>
    <Members>
    <ScriptProperty>
    <Name>BigEndianAddress</Name>
    <GetScriptBlock>
    $bytes=$this.GetAddressBytes()
    [array]::Reverse($bytes)
    [BitConverter]::ToUInt32($bytes,0)
    </GetScriptBlock>
    </ScriptProperty>
    </Members>
    </Type>
    </Types>


      My System SpecsSystem Spec

  9. #9


    Martin Brill Guest

    Re: IP Addresses sort with Powershell

    Hello Keith,

    >>>

    132> gc ips.txt | %{"{0:000}.{1:000}.{2:000}.{3:000}" -f
    @([int[]]$_.split('.'))} |
    sort | %{"{0}.{1}.{2}.{3}" -f @([int[]]$_.split('.'))}
    1.5.5.5
    2.4.53.233
    12.24.3.78
    124.5.6.8
    234.2.5.7

    That's 129 chars to type versus your original comand that was ~120. The
    primary trick with this approach in powershell is that once you split on '.'
    you need to convert each part into a number.
    <<<

    I'm happy, great work. Thanks for the different solutions. You are my hero.
    :-)

    Best regards
    Martin


      My System SpecsSystem Spec

  10. #10


    Martin Brill Guest

    Re: IP Addresses sort with Powershell

    Hi Kiron,

    > Your 'lexigraphical' solution could be shorter:
    >
    > gc ips.txt | % {"{0}.{1}.{2}.{3}" -f @([int[]]$_.split('.'))} | sort


    Thanks, but this shorter version show not the same result:

    PS C:\Users\Martin> gc ips | %{"{0:000}.{1:000}.{2:000}.{3:000}" -f
    @([int[]]$_.split('.'))} | sort | %{"{0}.{1}.{2}.{3}" -f
    @([int[]]$_.split('.'))}

    1.5.5.5
    2.4.53.233
    12.24.3.78
    124.5.6.8
    234.2.5.7
    234.2.5.7

    PS C:\Users\Martin> gc ips | % {"{0}.{1}.{2}.{3}" -f
    @([int[]]$_.split('.'))} | sort

    1.5.5.5
    12.24.3.78
    124.5.6.8
    2.4.53.233
    234.2.5.7

    Best regards
    Martin


      My System SpecsSystem Spec

Page 1 of 5 123 ... LastLast
IP Addresses sort with Powershell problems?

Similar Threads
Thread Thread Starter Forum Replies Last Post
XML Node sort in powershell @lways PowerShell 2 23 Apr 2010
How to configure a NIC with 2 IP addresses in powershell gn!uz PowerShell 1 09 Sep 2009
Sort an array of numbers in Powershell stephenodonoghue PowerShell 4 17 Dec 2008
Re: Can I sort within a sort, in folder view (eg., Name, Date) Baffin Live Mail 0 09 Dec 2007
Sort by name doesnt sort correctly in my opinion douglasgblake Vista file management 5 08 Aug 2007