perl -pi -e "s/\x22message\x22\s+\x22Боже, ты посмотри вокруг, что происходит!\x22/\x22message\x22 \x22\x22/g;" "D:\Sav\scripts\chat_wheel.txt"
No hay nada malo con este comando excepto por la porción de texto en ruso que quiero eliminar
¡Dios, mira a tu alrededor, qué está pasando!
Cuando lo ejecuto en cmd.exe, aparece el siguiente mensaje de error.
Cuantificadores anidados en expresiones regulares; marcado por <-- AQUÍ en m/\x22message\x22\s+\x22??? <-- AQUÍ?,?????????????????,?????????????!\x22/ en -e línea 1.
Entonces, ¿cómo reemplazo la frase rusa mientras mantengo el comando como una sola línea? ¿es posible?
Mi consola usa CP 65001 (UTF-8). [De Win32::GetConsoleCP()
]
Mi página de códigos activa (ACP) es 1252 [De Win32::GetACP()
].
Mi archivo está codificado con UTF-8.
Solución del problema
Б
está siendo reemplazado por ?
. Esto se debe a que no es compatible con la página de códigos de la consola, la página de códigos activa o ambas.
La página de códigos de su consola está establecida en 65001 o UTF-8. Por lo tanto, su consola puede manejar cualquier carácter en el juego de caracteres Unicode. El problema obviamente no está aquí.
Cada llamada al sistema de Windows que maneja cadenas viene en dos variedades. Una variedad "W"ide que usa UTF-16le y una variedad "A"NSI que usa la página de código activa. Si Perl usara la interfaz "W" para tomar sus parámetros de línea de comandos, no tendríamos este problema. En cambio, Perl usa la interfaz "A" para esta (y todas las demás) llamadas al sistema.
Esto significa que Perl solo puede aceptar argumentos de línea de comandos que pueden ser representados por la página de códigos activa. En su caso, es 1252 y el conjunto de caracteres cp1252 no incluye caracteres cirílicos.
Suponiendo que no queremos reemplazar cada carácter con un escape (como cuando reemplazó las comillas dobles con "
), necesitaremos hacer algo diferente.
Como no podemos pasar el script usando un argumento, necesitaremos proporcionarlo usando un archivo en lugar de usar -e
. O a través de una tubería.
echo s/"message"\s+"\KБоже(?=")// | perl -i -p - file.txt
Una solución mejor pero más drástica sería cambiar el ACP de Perl a 65001.
Hay un segundo problema.
Perl espera que su código fuente se codifique usando ASCII (limpio de 8 bits) a menos que proporcione use utf8;
. Entonces, mientras piensas que estás pasando s/...Боже...//
, en realidad estás pasando s/...\xD0\x91\xD0\xBE\xD0\xB6\xD0\xB5...//
.
Esto funciona bien, en parte porque tampoco decodificas tu archivo de entrada. Pero puede dar lugar a sorpresas. Por ejemplo, "Б" =~ /^[Бж]\z/
( "\xD0\x91" =~ /^[\xD0\x91\xD0\xB6]\z/
) devolvería falso!
Para arreglar esto en un script, usarías
use utf8; # Source code is using UTF-8.
use open ':std', ':encoding(UTF-8)'; # Terminal provides & expects UTF-8.
-C
hará aquí.
echo s/"message"\s+"\KБоже(?=")// | perl -i -C -p - file.txt
No hay comentarios.:
Publicar un comentario