web-dev-qa-db-fra.com

Conflit entre substitution de variable et caractères CJK dans BASH

J'ai rencontré un problème de substitution de variable dans le shell BASH.
Disons que vous définissez une variable a. Ensuite, la commande

    $> echo ${a//[0-4]/}

imprime sa valeur avec tous les nombres compris entre 0 et 4 supprimés:

    $> a="Hello1265-3World"
    $> echo ${a//[0-4]/}
    Hello65-World

Cela semble très bien fonctionner, mais jetons un coup d'œil à l'exemple suivant:

    $> b="你1265-3好"
    $> echo ${b//[0-4]/}
    你1265-3好

La substitution n'a pas eu lieu: je suppose que c'est parce que b contient des caractères CJK. Ce problème s'étend à tous les cas dans lesquels des crochets sont impliqués. Étonnamment, la substitution de variables sans crochets fonctionne bien dans les deux cas:

    $> a="Hello1265-3World"
    $> echo ${a//2/}
    Hello165-3World
    $> b="你1265-3好"
    $> echo ${b//2/}
    你165-3好

Est-ce un bug ou est-ce que je manque quelque chose?

J'utilise Lubuntu 12.04, le terminal est lxterminal et echo $BASH_VERSION renvoie la version 4.2.24 (1).

EDIT: Andrew Johnson dans son commentaire a déclaré qu'avec gnome-terminal 4.2.37 (1) - relâchez la commande fonctionne très bien. Je me demande s'il s'agit d'un problème de lxterminal ou de sa version spécifique 4.2.24 (1).

EDIT: Je l'ai essayé avec gnome-terminal sur Lubuntu 12.04 mais le problème est toujours là ...

6
AndreasT

Réponse courte:

définissez LC_ALL = C pour le comportement que vous attendez

pauhel@permafrost:~$ b="你1265-3好"
paul@permafrost:~$ echo ${b//[0-2]/}
你1265-3好
paul@permafrost:~$ export LC_ALL=C
paul@permafrost:~$ echo ${b//[0-2]/}
你65-3好

Longue réponse:

Le comportement que vous attendez repose sur l'ordre de classement qui dépend de la mise en œuvre locale/OS. Le standard POSIX le laisse spécifiquement indéfini à l'exception des paramètres régionaux C. (Bash appelle une bibliothèque externe pour cela et, à première vue, il semble que cela revient à ASCII ordre si seulement ASCII caractères sont présents).

Les versions ultérieures de bash ont une option Shell qui vous permet de spécifier quelque chose comme vous vous attendez.

Voir:

https://groups.google.com/forum/#!topic/gnu.bash.bug/S6cN9KI4vK4/discussion

pour plus de fond.

2
tallus