El comando cut
tiene una opción -c
para trabajar en caracteres, en lugar de bytes con la opción -b
. Pero eso no parece funcionar, en la en_US.UTF-8
configuración regional:
El segundo byte proporciona el segundo carácter ASCII (que está codificado de la misma manera en UTF-8):
$ printf 'ABC' | cut -b 2
B
pero no da el segundo de tres caracteres griegos no ASCII en la configuración regional UTF-8:
$ printf 'αβγ' | cut -b 2
�
Está bien, es el segundo byte .
Entonces miramos el segundo personaje en su lugar:
$ printf 'αβγ' | cut -c 2
�
Eso se ve roto.
Con algunos experimentos, resulta que el rango 3-4
muestra el segundo personaje:
$ printf 'αβγ' | cut -c 3-4
β
Pero eso es lo mismo que los bytes 3 a 4:
$ printf 'αβγ' | cut -b 3-4
β
Entonces el -c
no hace más que el -b
UTF-8.
Esperaría que la configuración regional no sea adecuada para UTF-8, pero en comparación, wc
funciona como se esperaba;
A menudo se usa para contar bytes, con la opción -c
( --bytes
).
(Tenga en cuenta los nombres confusos de las opciones).
$ printf 'αβγ' | wc -c
6
Pero también puede contar caracteres con la opción -m
( --chars
), que simplemente funciona:
$ printf 'αβγ' | wc -m
3
Así que mi configuración parece estar bien, pero hay algo especial en esto cut
.
Tal vez no es compatible con UTF-8 en absoluto? Pero parece admitir caracteres de varios bytes, de lo contrario no necesitaría admitir -b
y -c
.
¿Así que qué hay de malo? ¿Y por qué?
La configuración regional parece correcta para utf8, por lo que puedo decir:
$ 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=
La entrada, byte por byte:
$ printf 'αβγ' | hd
00000000 ce b1 ce b2 ce b3 |......|
00000006
fuente
-c
está usando el mismo código que-b
. ¿Le echó un vistazo al código fuente? Tal vez puedas encontrar una pista de lo-c
que realmente está destinado.Respuestas:
No ha dicho cuál
cut
está usando, pero como ha mencionado la opción larga GNU--characters
, supondré que es esa. En ese caso, tenga en cuenta este pasaje deinfo coreutils 'cut invocation'
:(énfasis añadido)
Por el momento, GNU
cut
siempre funciona en términos de "caracteres" de un solo byte, por lo que se espera el comportamiento que ve.Apoyando tanto los
-b
y-c
las opciones está requerido por POSIX - que no se han añadido a GNUcut
porque tenía el apoyo de varios bytes y que funcionaba correctamente, pero para evitar errores en la entrada compatible con POSIX. Lo mismo-c
se ha hecho en algunas otrascut
implementaciones, aunque no en FreeBSD y OS X al menos.Este es el comportamiento histórico de
-c
.-b
se agregó recientemente para asumir el rol de byte para que-c
pueda funcionar con caracteres de varios bytes. Tal vez en unos pocos años funcione de la manera deseada, aunque el progreso no haya sido rápido (ya ha pasado más de una década). GNUcut
ni siquiera implementa la-n
opción aún, a pesar de que es ortogonal y está destinada a ayudar en la transición. Existen posibles problemas de compatibilidad con scripts antiguos, lo que puede ser un problema, aunque no sé definitivamente cuál es el motivo.fuente
tr
documentos de GNU también. e incluso atar
menos que lo recuerde mal. Supongo que es un gran proyecto.cut
? Por ejemplo, ¿dónde es posible descargar las fuentes para parchescut
? ¿O sería más fácil usar otra utilidad? (grep
Solución por debajo de no funciona sin problemas con rangos por ejemplo5-8,44-49
)cut -c
aquí: superuser.com/questions/506164/...colrm
(parte deutil-linux
, ya debería estar instalado en la mayoría de las distribuciones) parece manejar la internacionalización mucho mejor:Tenga cuidado con la numeración:
colrm N
eliminará columnas deN
, imprimiendo caracteres hastaN-1
.( créditos )
fuente
Dado que muchas
grep
implementaciones son compatibles con varios bytes, también puede usargrep -o
para simular algunos usos decut -c
.Ajuste el número de períodos para simular
cut
rangos.fuente