La commande cut
a une option -c
pour travailler sur des caractères, au lieu d'octets avec l'option -b
. Mais cela ne semble pas fonctionner, en en_US.UTF-8
locale:
Le deuxième octet donne le deuxième caractère ASCII (qui est codé de la même manière en UTF-8):
$ printf 'ABC' | cut -b 2
B
mais ne donne pas le deuxième des trois caractères grecs non ASCII dans les paramètres régionaux UTF-8:
$ printf 'αβγ' | cut -b 2
�
C'est bien - c'est le deuxième octet .
Nous regardons donc le deuxième caractère à la place:
$ printf 'αβγ' | cut -c 2
�
Ça a l'air cassé.
Avec quelques expériences, il s'avère que la plage 3-4
montre le deuxième caractère:
$ printf 'αβγ' | cut -c 3-4
β
Mais c'est exactement la même chose que les octets 3 à 4:
$ printf 'αβγ' | cut -b 3-4
β
Donc, -c
ne fait pas plus que -b
pour UTF-8.
Je m'attendrais à ce que la configuration locale ne soit pas correcte pour UTF-8, mais en comparaison, wc
fonctionne comme prévu;
Il est souvent utilisé pour compter les octets, avec l'option -c
( --bytes
).
(Notez les noms d'options confus.)
$ printf 'αβγ' | wc -c
6
Mais il peut également compter les caractères avec l'option -m
( --chars
), qui fonctionne simplement:
$ printf 'αβγ' | wc -m
3
Ma configuration semble donc correcte - mais quelque chose de spécial cut
.
Peut-être qu'il ne prend pas du tout en charge l'UTF-8? Mais il semble prendre en charge les caractères multi-octets, sinon il n'aurait pas besoin de prendre en charge -b
et -c
.
Alors, qu'est-ce qui ne va pas? Et pourquoi?
La configuration locale semble correcte pour utf8, pour autant que je sache:
$ locale
LANG=en_US.UTF-8
LANGUAGE=en_US
LC_CTYPE=en_US.UTF-8
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=
L'entrée, octet par octet:
$ printf 'αβγ' | hd
00000000 ce b1 ce b2 ce b3 |......|
00000006
la source
-c
utiliser le même code que-b
. Avez-vous regardé le code source? Vous pouvez peut-être trouver un indice de ce à quoi il-c
est réellement destiné.Réponses:
Vous n'avez pas dit lequel
cut
vous utilisez, mais puisque vous avez mentionné l'option longue GNU,--characters
je suppose que c'est celle-là. Dans ce cas, notez ce passage deinfo coreutils 'cut invocation'
:(pas d'italique dans l'original)
Pour le moment, GNU
cut
fonctionne toujours en termes de "caractères" à un octet, donc le comportement que vous voyez est attendu.POSIX prend en charge à la fois les options
-b
et - elles n'ont pas été ajoutées à GNU car il avait une prise en charge multi-octets et elles fonctionnaient correctement, mais pour éviter de donner des erreurs sur les entrées compatibles POSIX. La même chose a été faite dans certaines autres implémentations, mais pas pour FreeBSD et OS X au moins.-c
cut
-c
cut
C'est le comportement historique de
-c
.-b
a été récemment ajouté pour prendre en charge le rôle d'octets afin de-c
pouvoir fonctionner avec des caractères multi-octets. Peut-être que dans quelques années, cela fonctionnera comme souhaité de manière cohérente, bien que les progrès n'aient pas été rapides (cela fait déjà plus d'une décennie). GNUcut
n'implémente même pas encore cette-n
option , même si elle est orthogonale et destinée à faciliter la transition. Il existe des problèmes de compatibilité potentiels avec les anciens scripts, ce qui peut être un problème, bien que je ne sache pas définitivement quelle est la raison.la source
tr
documents de GNU . et mêmetar
si je ne me souviens pas. je suppose que c'est un gros projet.cut
? Par exemple, où est-il possible de télécharger les sources pour patchécut
? Ou serait-il plus facile d'utiliser un autre utilitaire? (lagrep
solution ci-dessous ne fonctionne pas correctement avec les plages, par exemple5-8,44-49
)cut -c
ici: superuser.com/questions/506164/…colrm
(une partie deutil-linux
, devrait déjà être installé sur la plupart des distributions) semble gérer l'internationalisation beaucoup mieux:Méfiez-vous de la numérotation:
colrm N
supprimera les colonnes deN
, en imprimant les caractères jusqu'àN-1
.( crédits )
la source
Étant donné que de nombreuses
grep
implémentations sont compatibles avec plusieurs octets, vous pouvez également utilisergrep -o
pour simuler certaines utilisations decut -c
.Ajustez le nombre de périodes pour simuler des
cut
plages.la source