почему во втором случае съедается вторая строка?
я чего-то в жизни не понимаю?
ну хорошо. допустим, "1.1" считается числом с плавающей точкой, а "1.1.1" — это, типа, «число, после которого — мусор».
но ведь в третьем случае правильно сортирует!
Если встречаются несколько строк, которые при выбранном способе сортировки считаются равными, то -u удаляет все, кроме одной. -n выбирает сортировку по числу, находящемуся в начале строки. Если это число одно и то же, то -u, соответственно, удалит все строки с этим числом, кроме одной.
а вот -un имеет какаю-то инопланетянскую логику.
я бы, честно говоря, ни в жисть до такого не додумался.
Не -un, а -u в сочетании с любым флагом, уточняющим критерии сортировки. Только эти уточнённые критерии и будут использоваться для сравнения строк, и в т.ч. для удаления дублей.
третий пример этому противоречит. порядок строк поменялся, хотя число там одно и то же.
Не противоречит. По-умолчанию используется более эффективный, но нестабильный алгоритм. Для использования стабильного нужно указать флаг -s.
гхм. а где написано про то, что -s использует «более эффективынй» (чем -sn) алгоритм?
и где написано про то, что -un будет сортировать «более стабильным способом», чем -n?
ни в man-е ни в info что-то не вижу про это ни слова. надо протереть иллюминаторы?
гхм. а где написано про то, что -s использует «более эффективынй» (чем -sn) алгоритм?
и где написано про то, что -un будет сортировать «более стабильным способом», чем -n?
А где я это сказал? o_O
Специально для непонятливых. Повторяю _всё_, что я сказал в этой теме, в кратком виде.
* Если есть ключи, задающие способ сравнения строк (например, -n), то _только этот способ_ и используется для их сравнения. В том числе и для удаления одинаковых через -u.
* Если _не_ указан ключ -s, то (независимо от прочих ключей) происходит сортировка _нестабильным_ (a.k.a. _неустойчивым_) алгоритмом. Это означает, что строки, считающиеся одинаковыми, могут быть переставлены друг с другом труднопредсказуемым образом. Ключ -s же гарантирует, что они останутся в том же порядке, в котором были.
Надо же. Я как-то никогда не задумывался, чем опция sort-а u отличается от uniq. А оказывается, отличается принципиально.
насколько я вижу, отличается не столько "-u", сколько сочетание "-un". "-u" работает вполне разумно:
Я имел ввиду то, о чём уже сказал Олег: не только с n, но с любым «уточняющим» ключом. Например, очень полезного эффекта можно добиться сочетанием «-ukM,N». И неразумным я бы такое поведение точно не назвал. Скорее не очень разумно отсутствие достаточно подробного описания в мане.
спасибо за разъяснение. интересовался я в основном другим — _где_ эти знания были почерпнуты. насколько я вижу — не в man/info (или иллюминаторы у меня всё-таки запотели?).
-u Unique: suppress all but one in each set of lines having equal
keys. If used with the -C or -c options, also check that there
are no lines with duplicate keys.
DESCRIPTION
With the "sort" pragma you can control the behaviour of the builtin
"sort()" function.
In Perl versions 5.6 and earlier the quicksort algorithm was used to
implement "sort()", but in Perl 5.8 a mergesort algorithm was also made
available, mainly to guarantee worst case O(N log N) behaviour: the
worst case of quicksort is O(N**2). In Perl 5.8 and later, quicksort
defends against quadratic behaviour by shuffling large arrays before
sorting.
A stable sort means that for records that compare equal, the original
input ordering is preserved. Mergesort is stable, quicksort is not.
Stability will matter only if elements that compare equal can be
distinguished in some other way. That means that simple numerical and
lexical sorts do not profit from stability, since equal elements are
indistinguishable. However, with a comparison such as
{ substr($a, 0, 3) cmp substr($b, 0, 3) }
stability might matter because elements that compare equal on the first
3 characters may be distinguished based on subsequent characters. In
Perl 5.8 and later, quicksort can be stabilized, but doing so will add
overhead, so it should only be done if it matters.
The best algorithm depends on many things. On average, mergesort does
fewer comparisons than quicksort, so it may be better when complicated
comparison routines are used. Mergesort also takes advantage of pre-
existing order, so it would be favored for using "sort()" to merge
several sorted arrays. On the other hand, quicksort is often faster
for small arrays, and on arrays of a few distinct values, repeated many
times. You can force the choice of algorithm with this pragma, but
this feels heavy-handed, so the subpragmas beginning with a "_" may not
persist beyond Perl 5.8. The default algorithm is mergesort, which
will be stable even if you do not explicitly demand it. But the
stability of the default sort is a side-effect that could change in
later versions. If stability is important, be sure to say so with a
use sort 'stable';
The "no sort" pragma doesn't forbid what follows, it just leaves the
choice open. Thus, after
no sort qw(_mergesort stable);
вообще говоря очевидно, что массив 1,1,1 после сортировки останется таким-же. Однако, никто не гарантировал, что сортировка не станет менять местами эти единички. Будет. Если ей так удобнее. qsort почти всегда меняет.
Полагаю, что при указании ключа -n, по каждой строке рассчитывается числовой (numeric) ключ, которые впоследствии и используются для сравнения. Для 1.1.1 получается ключ 1.1, для 1.1.2 получается ключ 1.1, строки 1.1.1 и 1.1.2 хотя и не равны лексикографически, имеют равные ключи сортировки -- 1.1.
Ключ -u заставляет подавлять вывод строк с неуникальными ключами, будет выведена только одна строка с ключом 1.1. В данном случае -- первая из встретившихся -- "1.1.2".
Ключ -u заставляет подавлять вывод строк с неуникальными ключами, будет выведена только одна строка с ключом 1.1. В данном случае -- первая из встретившихся -- "1.1.2".
ИМХО нет. Строки сначала сортируются, а потом выводится первое в отсортированном. В силу того, что сортировка неустойчивая, строки с равными ключами могут поменяться местами. И если сейчас (если верить моему мануалу) сортировка устойчивая, то в будущих версиях (если верить тому-же мануалу) она может стать неустойчивой, и порядок строк будет меняться.
И если сейчас (если верить моему мануалу) сортировка устойчивая, то в будущих версиях (если верить тому-же мануалу) она может стать неустойчивой, и порядок строк будет меняться.
Чтобы она была устойчивой, используется ключ -s. А без него лично у меня и сейчас неустойчивая.
Вообще, у меня такой ощущение, что у вас sort не из gnu coreutils, а какой-то другой.
The
IPv4 addresses are sorted lexicographically. The second sort uses
`-s' so that ties in the primary key are broken by the secondary
key; the first sort uses `-s' so that the combination of the two
sorts is stable.
ну а понятие "(не)стабильная сортировка" вообще говоря к sort не имеет отношения. и к линуксу вообще. Это ИМХО теория алгоритмов, и в мане достаточно написать, что по второму ключу сортировка даёт неожиданный результат, ибо нестабильная.