Примечание. Этот ответ посвящен общему случаю сортировки целых строк (по всем их символов, а не только по первому одному ).
Вы ищете порядковый номер сортировку , где символы сортируются численно по их кодовой точке Unicode ("значение ASCII" ) и поэтому все заглавные буквы , как группа, сортировать перед всеми строчными буквами .
Начиная с Windows PowerShell v5.1 / PowerShell Core v6.1.0, Sort-Object
неизменно использует слово сортировку (с использованием инвариант культура по умолчанию, но это можно изменить с помощью параметра -Culture
, где сортировка с учетом регистра просто означает, что строчная форма данной буквы непосредственно перед его заглавной формой, не все буквы вместе ; например, b
сортирует до B
, но оба они идут после обоих a
и A
(также логика обратна от порядкового регистра, где на первом месте стоят заглавные буквы ):
PS> 'B', 'b', 'A', 'a' | Sort-Object -CaseSensitive
a
A
b
B
Следовательно, для порядкового номера сортировки в настоящее время вы должны использовать .NET Framework напрямую (но обратите внимание, что расширение Sort-Object
рассматривается ):
# Get the last 50 lines as a list.
[Collections.Generic.List[string]] $lines = Get-Content -Tail 50 $filename
# Sort the list in place, using ordinal sorting
$lines.Sort([StringComparer]::Ordinal)
# Output the result.
# Note that uppercase letters come first.
$lines
[StringComparer]::Ordinal
возвращает объект, который реализует интерфейс [System.Collections.IComparer]
.
Использование этого решения в конвейере возможно, но нетривиально (массив строк отправляется один элемент):
(, (Get-Content -Tail 50 $filename)) | ForEach-Object {
($lines = [Collections.Generic.List[string]] $_).Sort([StringComparer]::Ordinal)
$lines # output the sorted lines
}
Примечание: Как уже говорилось, это сортирует прописные буквы буквы первые .
Чтобы отсортировать все строчные буквы сначала , вам необходимо реализовать пользовательскую сортировку с помощью [System.Comparison[string]
делегата , который в PowerShell может быть реализован как блок сценария ({ ... }
), который принимает две входные строки и возвращает их рейтинг сортировки (-1
(или любое отрицательное значение) для меньше , 0
для равно , 1
(или любое положительное значение) для больше чем ):
$lines.Sort({ param([string]$x, [string]$y)
# Determine the shorter of the two lengths.
$count = if ($x.Length -lt $y.Length) { $x.Length } else { $y.Length }
# Loop over all characters in corresponding positions.
for ($i = 0; $i -lt $count; ++$i) {
if ([char]::IsLower($x[$i]) -ne [char]::IsLower($y[$i])) {
# Sort all lowercase chars. before uppercase ones.
return (1, -1)[[char]::IsLower($x[$i])]
} elseif ($x[$i] -ne $y[$i]) { # compare code points (numerically)
return $x[$i] - $y[$i]
}
# So far the two strings compared equal, continue.
}
# The strings compared equal in all corresponding character positions,
# so the difference in length, if any, is the decider (longer strings sort
# after shorter ones).
return $x.Length - $y.Length
})
Примечание: для английского текста вышеприведенное должно работать нормально, но для поддержки всего текста Unicode, потенциально содержащего суррогатные пары код-единица и различные формы нормализации (составленные против разложенных ударных символов), требуется еще больше работы.