Comment sortinger les lignes avec >> équerres doubles?

Il semble que cette sort se comporte étrangement sur des lignes telles que >>b

 $ cat test a >>b b c > >> $ sort test > >> a b >>b c 

Je m'attendrais à ce que la ligne >>b soit la troisième ligne de sortie par sort mais elle est la cinquième. Pourquoi fait-il cela et y a-t-il un moyen de faire en sort donner mon résultat attendu?

J'utilise GNU / Linux Ubuntu 16.04.

Les algorithms de sorting dans les environnements modernes sont assez complexes.

Chaque caractère (en fait, l' élément d'assemblage qui pourrait consister en une séquence de plusieurs caractères comme le ch tchèque) reçoit un certain nombre de poids de collationnement qui décident de leur ordre de sorting.

Lors de la comparaison de deux strings, le premier poids de tous les caractères est utilisé en premier, et d'autres poids sont utilisés plus tard pour décider des liens si les deux strings sont sortingées de la même façon avec les premiers poids.

Par exemple, dans de nombreux endroits, e , é et E ont le même poids primaire (ils appartiennent à la même class d'équivalence, ils correspondent tous à [=e=] ).

Ainsi, en comparant par exemple echo , été et Enter , dans la première passe, e , é et E ayant le même poids primaire, c'est le second caractère qui déterminera l'ordre ( c avant n avant t ).

En comparant été , été , Ete , après la première passe, ils sont tous identiques, nous utilisons donc la deuxième passe en utilisant le poids secondaire. Dans les locales GNU typiques, le deuxième poids pour les caractères de script latin est utilisé pour donner la priorité aux accents (aucun accent ne vient en premier, puis aigu, grave, breve, circonflexe …). Nous aurons alors besoin d'utiliser le troisième poids pour décider entre été et Été et qui sera basé sur le cas (minuscule en premier dans la plupart des endroits). Il y a même des personnages qui finissent par sortinger les mêmes car tous leurs poids sont identiques.

Cela est utilisé pour sortinger le text de la même manière que les dictionarys, comme le ferait un humain.

Dans un dictionary, vous findez cet espace et la plupart des caractères de ponctuation sont également ignorés. Par exemple, de facto types de facto entre debut et devoid . Le premier poids du caractère espace est IGNORE.

Sur un système GNU, vous findez les règles d'assemblage de base définies dans le /usr/share/i18n/locales/iso14651_t1_common (le path peut varier selon la dissortingbution). Là, vous verrez:

 ifdef UPPERCASE_FIRST <CAP> else <MIN> endif [...] ifdef UPPERCASE_FIRST [...] <MIN> # 10 [...] else [...] <CAP> # 9 [...] endif [...] order_start <SPECIAL>;forward;backward;forward;forward,position <U0020> IGNORE;IGNORE;IGNORE;<U0020> # 32 <SP> [...] <U003E> IGNORE;IGNORE;IGNORE;<h> # 140 > [...] ifdef DIACRIT_FORWARD order_start <LATIN>;forward;forward;forward;forward,position else order_start <LATIN>;forward;backward;forward;forward,position endif [...] <U0065> <e>;<BAS>;<MIN>;IGNORE # 259 e <U00E9> <e>;<ACA>;<MIN>;IGNORE # 260 é [...] <U0045> <e>;<BAS>;<CAP>;IGNORE # 577 E <U00C9> <e>;<ACA>;<CAP>;IGNORE # 578 É 

Ce qui illustre ce que nous venons de dire. L'espace et > ont leurs 3 premiers poids réglés sur IGNORE . C'est seulement pour les strings qui sortingent les 3 premiers poids que leur ordre relatif sera considéré ( > avant l'espace que <h> <U0020> avant le symbole de <U0020> non spécifié <U0020> ).

Dans les parameters régionaux qui définissent UPPERCASE_FIRST (comme /usr/share/i18n/locales/tr_TR ), les majuscules viendront en premier (dans la 3ème passe). Idem avec DIACRIT_FORWARD où certains parameters locaux comme de_DE peuvent décider d'inverser l'ordre des signes diacritiques pour la 2ème passe.

> et >> identiques dans les 1 er , 2 e et 3 e passes. Dans le 4ème, > sortinge avant >> que la corde vide sortinge avant tout.

>>b sortinge après b car ils sortingent les mêmes dans les 3 premières passes, mais dans la quasortingème passe, b est IGNORE, donc > est plus grand. C'est less que c dans la première passe ( > ignoré, et b avant c ) … Vous avez l'idée.

Maintenant, si vous regardez la définition des parameters régionaux C C'est beaucoup plus simple. Il n'y a qu'un seul poids, et le poids est basé sur la valeur de code de U + 0000 à U + 10FFFF. Donc SPC (U + 0020) sortinge avant > (U + 003E), qui sortinge avant b (U + 0062) qui sortinge avant c (U + 0063). Aucun personnage n'est jamais ignoré.

Notez qu'avec la version GNU libc au less, l'ordre défini dans le file de définition des parameters régionaux C est ignoré en ce qui concerne les fonctions de comparaison ( strcoll() et co.). Quelle que soit la valeur de LC_CTYPE , avec LC_COLLATE=C , strcoll() est équivalent à strcmp() . Comme dans la comparaison est toujours sur la valeur d'octet, même si ces octets correspondent à des caractères dont le code de code unicode sortinge l'inverse (comme 0xA4 U + 20AC EURO SIGN vs A5 U + 00A5 YEN SIGN dans le jeu de caractères ISO-8859-15) , alors LC_ALL=C sort et LC_COLLATE=C sort (si LC_ALL n'est pas défini) aura le même effet.

De la page de sort(1) man:

  *** WARNING *** The locale specified by the environment affects sort order. Set LC_ALL=C to get the traditional sort order that uses native byte values. 

Pour sortinger par valeur d'octet, utilisez:

 LC_ALL=C sort test 

Sinon, sort ignorera les caractères principaux jusqu'à ce qu'il rencontre une key sur laquelle il peut sortinger, ce qui explique pourquoi >>b et b sont adjacents les uns aux autres.