¿Cómo puedo obtener argumentos correctos de línea de comandos que no son de ASCII en activestate perl?

StackOverflow https://stackoverflow.com/questions/7824335

Pregunta

Ejecutando el siguiente comando

perl -e "for (my $i = 0; $i < length($ARGV[0]); $i++) {print ord(substr($ARGV[0], $i, 1)), qq{\n}; }" αβγδεζ

En una ventana CMD de Windows 7 con activestate perl v5.14.2 produce el siguiente resultado:

97
223
63
100
101
63

Los valores anteriores no son sensibles y no corresponden a ninguna codificación conocida, por lo que tratar de decodificarlos con el enfoque recomendado en¿Cómo puedo tratar los argumentos de la línea de comandos como UTF-8 en Perl? no ayuda. Cambiar la página del código activo de la ventana de comando no cambia los resultados.

¿Fue útil?

Solución

Su sistema, como todos los sistemas de Windows que conozco, utiliza de forma predeterminada la página de código ANSI 1252, por lo que podría intentar usar

use Encode qw( decode );
@ARGV = map { decode('cp1252', $_) } @ARGV;

Tenga en cuenta que CP1252 no puede representar a todos esos caracteres, por lo que la consola y, por lo tanto, Perl realmente recibe

  • un 97
  • ß 223
  • ? 63
  • D 100
  • E 101
  • ? 63

Hay una interfaz "amplia" para pasar (casi) cualquier código de unicode apuntando a un programa, pero

  1. La interfaz amplia no se usa cuando escribe un comando en el mensaje.
  2. Perl usa la interfaz ANSI para obtener los parámetros, por lo que incluso si comenzó a Perl usando la interfaz amplia, los parámetros se degradarían a ANSI cuando Perl los busque.

Lo siento, pero este es un tipo de situación "no puedes". Necesitas un enfoque diferente. Diomidis spinellis sugiere cambiar la página de código ANSI de su sistema de la siguiente manera en Win7:

  1. Panel de control
  2. Región e idioma
  3. Administrativo
  4. Lenguaje para programas no unicode
  5. Establezca el lenguaje actual para los programas no unicode en el lenguaje asociado con los caracteres específicos (griego en su caso).

En este punto, utilizaría la codificación de la página del código ANSI asociada con la nueva codificación seleccionada en lugar de cp1252 (cp1253 para griego).

use Encode qw( decode );
@ARGV = map { decode('cp1253', $_) } @ARGV;

Tenga en cuenta que usando chcp Para modificar la página de código utilizada dentro de la ventana de la consola, no afecta la página de código en la que Perl recibe sus argumentos, que siempre es una página de código ANSI. Ver los ejemplos a continuación (CP737 es el griego Página de código OEM, y CP1253 es el griego Página de código ANSI. Puede encontrar las codificaciones etiquetadas como 37 y M7 en este documento.)

C:\>chcp 737
Active code page: 737

C:\>echo αβγδεζ | od -t x1
0000000 98 99 9a 9b 9c 9d 20 0d 0a

C:\>perl -e "print map sprintf('%x ', ord($_)), split(//, $ARGV[0])" αβγδεζ
e1 e2 e3 e4 e5 e6

C:\>chcp 1253
Active code page: 1253

C:\>echo αβγδεζ | od -t x1
0000000 e1 e2 e3 e4 e5 e6 20 0d 0a

C:\>perl -e "print map sprintf('%x ', ord($_)), split(//, $ARGV[0])" αβγδεζ
e1 e2 e3 e4 e5 e6

Otros consejos

Esto funcionó para mí (en OS-X, pero debería ser portátil):

echo  αβγδεζ |perl -CI -e "chomp($in=<STDIN>);for (my $i = 0; $i < length($in); $i++) {print ord(substr($in, $i, 1)), qq{\n}; }"

Eso fue para Stdin; para argv:

perl -CA -e "for (my $i = 0; $i < length($ARGV[0]); $i++) {print ord(substr($ARGV[0], $i, 1)), qq{\n}; }" αβγδεζ

Ver el -C Opción en Perlrun: http://perdoc.perl.org/perlrun.html#command-switches

Si coloco los caracteres en un archivo (de OS-X), cópielo a un cuadro de Windows (como file.txt), entonces corre:

perl -CI -e "chomp($_=<STDIN>); map{print ord, qq{\n}} split(//)" < file.txt

Entonces obtengo lo esperado:

946
947
948
949
950

Pero si copio el contenido de file.txt A la línea de comando, obtengo galimatías.

Como decía @ikegami, no creo que sea posible hacer desde la línea de comandos ya que no tiene una ubicación UTF-8.

Podrías intentar usar https://metacpan.org/pod/win32::unicode::native. Debería tener lo que necesitas.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top