J'utilise bash sous Linux. J'obtiens un succès de l'instruction if suivante, mais cela ne devrait-il pas renvoyer un code d'échec?
if [[ ■ = [⅕⅖⅗] ]] ; then echo yes ; fi
Le carré n'égale aucun des caractères, donc je ne vois pas pourquoi j'obtiens un code de réussite.
Il est important pour moi de conserver les doubles crochets dans mon cas.
Y a-t-il une autre façon de faire une plage dans ce scénario, ou quelles autres suggestions?
C
n'est pas le cas ici car ce ne sont pas des caractères à un octet.C.UTF-8
ferait le cas échéant.Réponses:
C'est une conséquence du fait que ces caractères ont le même ordre de tri.
Vous remarquerez également que
renvoie une seule ligne.
Ou ça:
renvoie vrai (comme requis par POSIX).
La plupart des paramètres régionaux fournis avec les systèmes GNU ont un certain nombre de caractères (et même des séquences de caractères (séquences d'assemblage)) qui ont le même ordre de tri. Dans le cas de ces ■ ⅕⅖⅗, c'est parce que l'ordre n'est pas défini, et les caractères dont l'ordre n'est pas défini finissent par avoir le même ordre de tri dans les systèmes GNU. Il y a des caractères qui sont explicitement définis comme ayant le même ordre de tri comme Ș et Ş (bien qu'il n'y ait aucune logique ou cohérence réelle apparente (pour moi de toute façon) sur la façon dont cela est fait).
C'est la source de comportements assez surprenants et faux. J'ai soulevé la question très récemment sur la liste de diffusion du groupe Austin (le corps derrière POSIX et la spécification UNIX unique) et la discussion est toujours en cours depuis le 2015-04-03.
Dans ce cas, il
[y]
ne faut pas savoir si doit correspondrex
oùx
ety
trier la même chose, mais comme une expression entre crochets est censée correspondre à un élément de classement, cela suggère que lebash
comportement est attendu.En tout cas, je suppose
[⅕-⅕]
ou du moins[⅕-⅖]
devrait correspondre■
.Vous remarquerez que différents outils se comportent différemment. ksh93 se comporte comme
bash
, GNUgrep
oused
pas. Certains autres obus ont des comportements différents, certains commeyash
encore plus de buggy.Pour avoir un comportement cohérent, vous avez besoin d'un environnement local où tous les caractères sont triés différemment. La locale C est la locale typique. Cependant, le jeu de caractères dans les paramètres régionaux C sur la plupart des systèmes est ASCII. Sur les systèmes GNU, vous avez généralement accès à un
C.UTF-8
environnement local qui peut être utilisé à la place pour travailler sur le caractère UTF-8.Donc:
ou l'équivalent standard:
devrait retourner faux.
Une autre alternative serait de ne définir que
LC_COLLATE
C qui fonctionnerait sur les systèmes GNU, mais pas nécessairement sur d'autres où il pourrait ne pas spécifier l'ordre de tri des caractères multi-octets.L'une des leçons de cela est que l' égalité n'est pas une notion aussi claire qu'on pourrait s'y attendre lorsqu'il s'agit de comparer des chaînes. L'égalité peut signifier, du plus strict au moins strict.
Maintenant, pour 2 ou 3, cela suppose que les deux chaînes contiennent des caractères valides. En UTF-8 et certains autres encodages, certaines séquences d'octets ne forment pas de caractères valides.
1 et 2 ne sont pas nécessairement équivalents à cause de cela, ou parce que certains caractères peuvent avoir plus d'un codage possible. C'est généralement le cas des codages avec état comme ISO-2022-JP où
A
peut être exprimé comme41
ou1b 28 42 41
(1b 28 42
étant la séquence pour passer en ASCII et vous pouvez en insérer autant que vous le souhaitez, cela ne fera aucune différence), bien que je ne s'attendrait pas à ce que ces types d'encodage soient toujours utilisés, et les outils GNU au moins ne fonctionnent généralement pas correctement avec eux.Sachez également que la plupart des utilitaires non GNU ne peuvent pas gérer la valeur 0 octet (le caractère NUL en ASCII).
Laquelle de ces définitions est utilisée dépend de l'utilitaire et de sa mise en œuvre ou de sa version. POSIX n'est pas sûr à 100%. Dans les paramètres régionaux C, les 3 sont équivalents. En dehors de ce YMMV.
la source
é
eté
d'être la même chaîne, mais pase
. La notion d'ordre de classement de POSIX est rarement correcte, elle est trop fortement basée sur les caractères et ne tient pas compte des méthodes de tri les plus courantes (par exemple, les dictionnaires français n'utilisent pas un ordre lexicographique pour trier les mots: ils font un premier passage lexicographique avec des accents ignorés et puis utilisez des accents pour décider des liens).Vous vous trompez
=
et vous==
n'êtes pas le même.Essayez ces exemples:
la source
=
doit être utilisé pour vérifier l'égalité. Le problème, ce sont les guillemets manquants, pas l'opérateur.man bash
dans la[[
section: "L'opérateur = est équivalent à ==."[[...]]
opérateur. Et = et == sont les mêmes dans les shells où ils sont implémentés (ksh / bash / zsh) et pour la correspondance de motifs, pas l'égalité.