Manteniéndolo simple - cola
No deberíamos necesitar una expresión regular, o más de un proceso, solo para contar caracteres.
El comando tail
, que a menudo se usa para mostrar las últimas líneas de un archivo, tiene una opción -c
( --bytes
), que parece ser la herramienta adecuada para esto:
$ printf 123456789 | tail -c 3
789
(Cuando está en un shell, tiene sentido usar un método como en la respuesta de mikeserv, porque ahorra iniciar el proceso para tail
).
Personajes reales de Unicode?
Ahora, pides los últimos tres caracteres ; Eso no es lo que te da esta respuesta: ¡genera los últimos tres bytes !
Siempre que cada carácter sea un byte, tail -c
simplemente funciona. Por lo tanto, se puede utilizar si el conjunto de caracteres es ASCII
, ISO 8859-1
o una variante.
Si tiene una entrada Unicode, como en el UTF-8
formato común , el resultado es incorrecto:
$ printf 123αβγ | tail -c 3
�γ
En este ejemplo, usando UTF-8
, los caracteres griegos alfa, beta y gamma tienen dos bytes de longitud:
$ printf 123αβγ | wc -c
9
La opción -m
puede contar al menos los caracteres Unicode reales:
printf 123αβγ | wc -m
6
Ok, los últimos 6 bytes nos darán los últimos 3 caracteres:
$ printf 123αβγ | tail -c 6
αβγ
Por lo tanto, tail
no admite el manejo de caracteres generales, y ni siquiera lo intenta (ver más abajo): maneja líneas de tamaño variable, pero no caracteres de tamaño variable.
Digámoslo de esta manera: tail
es correcto para la estructura del problema a resolver, pero incorrecto para el tipo de datos.
GNU coreutils
Mirando más, resulta que los que te coreutils GNU, el conjunto de herramientas básicas como sed
, ls
, tail
y cut
, no está internacionalizado todavía completamente. Que se trata principalmente de soportar Unicode.
Por ejemplo, cut
sería un buen candidato para usar en lugar de la cola aquí para el soporte del personaje; Tiene opciones para trabajar en bytes o caracteres, -c
( --bytes
) y -m
( --chars
);
¡Solo eso -m
/ --chars
es, a partir de la versión
cut (GNU coreutils) 8.21
, 2013,
no implementado!
De info cut
:
`-c CHARACTER-LIST'
`--characters=CHARACTER-LIST'
Select for printing only the characters in positions listed in CHARACTER-LIST.
The same as `-b' for now, but internationalization will change that.
Consulte también esta respuesta a ¿No puede usar `cut -c` (` --characters`) con UTF-8? .
grep -o '.\{3\}$'