En mi nueva instalación de Arch, perl
no parece funcionar bien con Unicode. Por ejemplo, dado este archivo de entrada:
ελα ρε
王小红
Este comando debería darme los dos últimos caracteres de cada línea:
$ perl -CIO -pe 's/.*(..)$/$1/' file
ε
º¢
Sin embargo, como puedes ver arriba, entiendo un galimatías. La salida correcta es:
ρε
小红
Sé que mi terminal ( gnome-terminator
) admite UTF-8 ya que ambos funcionan como se esperaba:
$ cat file
ελα ρε
王小红
$ perl -pe '' file
ελα ρε
王小红
Desafortunadamente, sin -CIO
, perl
tampoco maneja los archivos correctamente:
$ perl -pe 's/.*(..)$/$1/' file
ε
��
Tampoco debería ser un problema local:
$ locale
LANG=en_US.UTF-8
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=
Supongo que necesito instalar algunos paquetes de Perl, pero no sé cuáles. Alguna información relevante:
$ perl --version | grep subversion
This is perl 5, version 22, subversion 0 (v5.22.0) built for x86_64-linux-thread-multi
$ pacman -Qs unicode
local/fribidi 0.19.7-1
A Free Implementation of the Unicode Bidirectional Algorithm
local/icu 55.1-1
International Components for Unicode library
local/libunistring 0.9.6-1
Library for manipulating Unicode strings and C strings
local/perl 5.22.0-1 (base)
A highly capable, feature-rich programming language
local/perl-unicode-stringprep 1.105-1
Preparation of Internationalized Strings (RFC 3454)
local/perl-unicode-utf8simple 1.06-5
Conversions to/from UTF8 from/to characterse
local/ttf-arphic-uming 0.2.20080216.1-5
CJK Unicode font Ming style
¿Cómo puedo hacer que mi instalación de Perl funcione bien con Unicode?
Respuesta1
El problema que estás describiendo es el comportamiento estándar en los sistemas que probé. I
y O
afecta stdin y stdout, por lo que esto debería funcionar:
→ cat data | perl -CIO -pe 's/.*(..)$/$1/'
ρε
小红
Mientras que esto podría no:
→ perl -CIO -pe 's/.*(..)$/$1/' data
ε
º¢
Haydos opciones más paraperl -C
que producen el comportamiento deseado.
i 8 UTF-8 is the default PerlIO layer for input streams
o 16 UTF-8 is the default PerlIO layer for output streams
Lo que básicamente significa que para Perl, use un formulario de apertura de archivo:
open(F, "<:utf8", "data");
o puedes usar perl -CSD
cual es una abreviatura deperl -CIOEio
S 7 I + O + E
D 24 i + o
Entonces obtienes
→ perl -CSD -pe 's/.*(..)$/$1/' data
ρε
小红
Si la PERLIO
variable de entorno está configurada e incluye, :utf8
este comportamiento también estaría habilitado.
Parece que el comportamiento predeterminado perl
tampoco se puede modificar en el momento de la configuración/compilación (comentario de Cuonglm a continuación). Arch ciertamente noestablecer cualquier cosa.Dudo que los paquetes de Debian Perl modifiquen el comportamiento predeterminado.
Respuesta2
Eso no es un problema del sistema sino del perl
mismo.
-CIO
solo configure la codificación UTF-8 en STDIN
y STDOUT
, dos de los tres identificadores de archivos predefinidos ( también perl
tiene -E
for ).STDERR
Cuando usas:
perl -CIO -pe 's/.*(..)$/$1/' file
perl
Utilice el operador de diamante <>
para procesar el archivo. Desde cuando el operador de diamantes <>
usóabierto (con forma de dos argumentos)para crear un nuevo identificador de archivo para cada archivo desde la línea de comando, estos identificadores de archivo no se verán afectados por la codificación UTF-8 que configuró STDIN
y STDOUT
.
Entonces, puedes pasar el contenido del archivo a perl
través de su entrada estándar y funcionará:
perl -CIO -pe 's/.*(..)$/$1/' <file
Para otras opciones ver@La respuesta de Matt.
En caso de que desee perl
utilizar su configuración regional para la capa de codificación predeterminada, puede utilizar:
perl -Mopen=:locale -pe 's/.*(..)$/$1/' file
Cuando utilice PERLIO
para configurar la capa de codificación, debeusar :encoding(uf8)
en lugar de:utf8
.
El uso :utf8
omite el paso de codificación y puede causar problemas al leer secuencias de bytes UTF-8 no válidas y provocar problemas de seguridad.