2010-11-10 8 views
12

Soy nuevo en power shell.clasificación personalizada en powershell

Mi problema es que que tengo los nombres de archivo en formato siguiente:

[ignore-prefix]-[important-middle]-[ignore-suffix]-[name-with-digits] 

necesito para ordenar de acuerdo a las reglas siguientes: en primer lugar por parte media, y luego por su nombre, en el orden natural (es decir, foobar10> foobar2) . No sé el valor del prefijo, pero sé el separador (guión).

así que mi primer intento, naturalmente:

filelist | Sort-Object -property @{Expression=` 
     {$_.FullName.SubString($_.FullName.IndexOf("-")+1)}} 

Esto tiene un problema que el sufijo afecta fin (ignore-aaa-1ignore-wname) se clasifican antes de ignorar-aaa-2ignore-aname), por lo que:

$filelist | Sort-Object -property @{Expression=` 
     {$_.FullName.SubString($_.FullName.IndexOf("-")+1,` 
     $_.FullName.SubString($_.FullName.IndexOf("-")+1).IndexOf("-"))}} 

Ok, eso ordena por el medio, pero ya inseguro. Si voy a agregar un tipo natural, eso sería aún peor. ¿Cuál es la manera más elegante de hacer eso?

Respuesta

11

Entiendo la tarea de esta manera: la clasificación debe realizarse mediante 3 expresiones: 1) parte central, 2) parte del nombre sin dígitos, 3) número representado por los dígitos finales de la parte del nombre.

Vamos a crear estas expresiones con expresiones regulares. Aquí está la respuesta:

# gets the middle part 
$part1 = { if ($_.Name -match '^[^-]+-([^-]+)') { $matches[1] } } 

# gets the name part with no digits 
$part2 = { if ($_.Name -match '^[^-]+-[^-]+-[^-]+-(\D+)') { $matches[1] } } 

# gets the number represented by digits from name (cast to [int]!) 
$part3 = { if ($_.Name -match '^[^-]+-[^-]+-[^-]+-\D+(\d+)') { [int]$matches[1] } } 

# sort it by 3 expressions 
$filelist | Sort-Object $part1, $part2, $part3 

Para una mejor comprensión de cómo funciona puede probar estas expresiones por separado:

$part1 = { if ($_.Name -match '^[^-]+-([^-]+)') { $matches[1] } } 
$part2 = { if ($_.Name -match '^[^-]+-[^-]+-[^-]+-(\D+)') { $matches[1] } } 
$part3 = { if ($_.Name -match '^[^-]+-[^-]+-[^-]+-\D+(\d+)') { [int]$matches[1] } } 

Write-Host '----- test1' 
$filelist | % $part1 

Write-Host '----- test2' 
$filelist | % $part2 

Write-Host '----- test3' 
$filelist | % $part3 

Como resultado, por ejemplo, estos archivos (extensión no es importante):

aaa-zzz-1ignore-wname10.txt 
aaa-zzz-1ignore-wname2.txt 
ignore-aaa-1ignore-wname10.txt 
ignore-aaa-1ignore-wname2.txt 

se ordenan como:

ignore-aaa-1ignore-wname2.txt 
ignore-aaa-1ignore-wname10.txt 
aaa-zzz-1ignore-wname2.txt 
aaa-zzz-1ignore-wname10.txt 
+0

"$ part1, $ part2, $ part2" debe ser "$ part1, $ part2, $ part3" gracias! – DennyRolling

+0

Sí, he notado eso, también. Fijo. –

Cuestiones relacionadas