Script para convertir caracteres ASCII a notación Unicode “”

Estoy haciendo algunos cambios en los archivos de configuración regional de Linux /usr/share/i18n/locales (como pt_BR ), y se requiere que las cadenas de formato (como %d-%m-%Y %H:%M ) se especifiquen en Unicode , donde cada carácter (en este caso, ASCII) se representa como .

Así que un texto como este:

 LC_TIME d_t_fmt "%a %d %b %Y %T %Z" d_fmt "%d-%m-%Y" t_fmt "%T" 

Debe ser:

 LC_TIME d_t_fmt "" d_fmt "" t_fmt "" 

Por lo tanto, necesito un script de línea de comandos (ya sea bash, Python, Perl o algo más) que tome una entrada como %d-%m-%Y y la convierta a .

Todos los caracteres en la cadena de entrada serían caracteres ASCII (de 0x20 a 0x7F ), por lo que esta es en realidad una conversión más elegante de “cadena de caracteres hexadecimal”.

¿Podría alguien ayudarme por favor? Mis habilidades en scripts de bash son muy limitadas, e incluso peores en Python.

Bonus por soluciones elegantes, explicadas.

¡Gracias!

(por cierto, este sería el script “inverso” para mi pregunta anterior )

Cada char con entrada de archivo

Si quisiera convertir todos los caracteres de un archivo a la representación de Unicode, entonces sería este sencillo de una sola línea

 while IFS= read -r -n1 c;do printf "" "'$c"; done < ./infile 

Cada personaje en STDIN

Si desea crear una herramienta similar a Unix que convierta la entrada en STDIN a una salida similar a Unicode, use esto:

 uni(){ c=$(cat); for((i=0;i<${#c};i++)); do printf "" "'${c:i:1}"; done; } 

Prueba de concepto

 $ echo "abc" | uni  

Sólo los caracteres entre comillas dobles

 #!/bin/bash flag=0 while IFS= read -r -n1 c; do if [[ "$c" == '"' ]]; then ((flag^=1)) printf "%c" "$c" elif [[ "$c" == $'\0' ]]; then echo elif ((flag)); then printf "" "'$c" else printf "%c" "$c" fi done < /path/to/infile 

Prueba de concepto

 $ cat ./unime LC_TIME d_t_fmt "%a %d %b %Y %T %Z" d_fmt "%d-%m-%Y" t_fmt "%T" abday "Dom";"Seg";/ here is a string with "multiline quotes";/ $ ./uni.sh LC_TIME d_t_fmt "" d_fmt "" t_fmt "" abday "";"";/ here is a string with " ";/ 

Explicación

Bastante simplemente realmente

  1. while IFS= read -r -n1 c; : Iterar sobre la entrada un carácter a la vez (a través de -n1 ) y almacenar el carácter en la variable c . Los indicadores IFS= y -r están allí para que la función incorporada de read no intente dividir palabras o interpretar secuencias de escape, respectivamente.
  2. if [[ "$c" == '"' ]]; si el char actual es una comilla doble
  3. ((flag^=1)) : Invierta el valor de flag desde 0-> 1 o 1-> 0
  4. elif [[ "$c" == $'\0' ]]; : Si el char actual es un NUL, entonces haga echo una nueva línea
  5. elif ((flag)) : si el indicador es 1, realice la transliteración de Unicode
  6. printf "" "'$c" : La magia que realiza la transcripción de Unicode. Tenga en cuenta que la comilla simple antes de $c es obligatoria, ya que le dice a printf que le estamos dando la representación ASCII de un número.
  7. else printf "%c" "$c" : imprime el carácter sin transliteración Unicode realizada

Usando Python

 #!/usr/bin/env python3.2 import sys text = sys.argv[1] encoded = "".join("".format(ord(char)) for char in text) print(encoded) 

Uso:

 $ python3 file.py "enter_input"  

(El mismo script debería funcionar tanto para Python 3.xy 2.x. Solo cambia la versión en shebang a la que tienes).

Explicación:

  1. Necesitamos importar el módulo sys para leer los argumentos de la línea de comandos.

  2. La lista sys.argv es la lista de todos los argumentos de la línea de comandos. La entrada [0] es el nombre del progtwig, la entrada [1] es el primer argumento, etc.

  3. f(char) for char in text es una expresión generadora . Se reproducirá en bucle para cada carácter en la variable de text , luego aplicará la función f en él y, finalmente, recostackrá el resultado como una lista perezosa ( iterable ).

  4. ord(char) encuentra el punto de código Unicode del carácter.

  5. "".format(x) es un método de formato de cadena descrito por el nombre. La cadena de formato toma 1 entrada x formato en formato 04X , es decir, cero 04X , ancho-4, mayúscula-hexadecimal.

  6. "".join(it) concatena todos los elementos en la lista perezosa (iterable). El "" significa que el separador es una cadena vacía.

  7. print(encoded) escribe la cadena encoded en stdout.

echo -n "aä" | ruby -KU -e '$<.chars{|c| print ""}; puts'

Salidas

-KU = $KCODE = "U"

Solución de script de shell:

 #!/bin/sh while IFS= read -r -n1 c; do printf "" "'$c"; done 

Esto lee la entrada estándar y se imprime en la salida estándar (suponiendo que haya puesto la secuencia de comandos en el archivo ejecutable en Unicode.sh ):

 > echo "hello" | toUnicode.sh  

Esto imprime el carácter EOF (el ), pero puede modificar este script para adaptarlo a sus necesidades, ya sea que desee leer la entrada una línea a la vez o recortarla o modificarla de otra manera.