2

Sorry guys..I am new to powershell. Would be great if someone help with the following scenario:

I have couple of files in a folder c:\test

sample.x.x.1
sample.x.x.2
sample.x.x.3
sample.x.x.4
sample.x.x.5

I want to find the name of the file which has the highest number in its name in the given folder. In the above example, 5 is the highest number and the script should return the output filename as sample.x.x.5

Thanks in advance!

David Brabant
  • 41,623
  • 16
  • 83
  • 111
coder coder
  • 53
  • 1
  • 7

2 Answers2

6

Sorting file names with numbers is quite a problem, as there are two ways. The first one sets them to alphabetical order. That is, 0, 1, 11, 111, 2,... The second one uses natural order. That is, 0, 1, 2, 11, 111.... This is surprisingly tricky and about every third programmer is confused with this.

There's a good answer already, which I'll refer like so,

# Create files 1..5
for($i=1;$i -le 5; ++$i) { set-content sample.x.x.$i -Value $null } 

# Tricksy! Create file .10 to confuse asciibetic/natural sorting
set-content sample.x.x.10 -Value $null

ls # Let's see the files

    Directory: C:\temp\test

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----       2015-09-28     10:29              0 sample.x.x.1
-a----       2015-09-28     10:29              0 sample.x.x.10
-a----       2015-09-28     10:29              0 sample.x.x.2
-a----       2015-09-28     10:29              0 sample.x.x.3
-a----       2015-09-28     10:29              0 sample.x.x.4
-a----       2015-09-28     10:29              0 sample.x.x.5

# Define helper as per linked answer
$ToNatural = { [regex]::Replace($_, '\d+$', { $args[0].Value.PadLeft(20,"0") }) }

# Sort with helper and check the output is natural result
gci | sort $ToNatural -Descending | select -First 1

Directory: C:\temp\test

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----       2015-09-28     10:29              0 sample.x.x.10
pcdev
  • 2,852
  • 2
  • 23
  • 39
vonPryz
  • 22,996
  • 7
  • 54
  • 65
  • 1
    Maybe worth noting that the asciibetic/numerical sorting issue arise from the *type* of the input object. If you know what substring you want to sort on, it's as easy as casting it to a numerical type: `sort { $_.Substring($_.LastIndexOf('.')+1) -as [int] }` – Mathias R. Jessen Sep 28 '15 at 10:36
1

Alphabetical sorting.

PS C:\Users\Gebb> @("sample.x.x.1", "sample.x.x.5", "sample.x.x.11") | sort
sample.x.x.1
sample.x.x.11
sample.x.x.5

Numerical sorting.

PS C:\Users\Gebb> @("sample.x.x.1", "sample.x.x.5", "sample.x.x.11") |
 sort -Property @{Expression={[Int32]($_ -split '\.' | select -Last 1)}}
sample.x.x.1
sample.x.x.5
sample.x.x.11

Largest number.

PS C:\Users\Gebb> @("sample.x.x.1", "sample.x.x.5", "sample.x.x.11") |
 sort -Property @{Expression={[Int32]($_ -split '\.' | select -Last 1)}} |
 select -Last 1
sample.x.x.11
Gebb
  • 6,371
  • 3
  • 44
  • 56