Ver puntos de código Unicode para todas las letras en el archivo en bash

10

Tengo que lidiar con un archivo que tiene muchos caracteres de control invisibles, como "de derecha a izquierda" o "ancho cero sin unión", espacios diferentes al espacio normal, etc., y tengo problemas para lidiar con eso.

Ahora, me gustaría de alguna manera ver todas las letras en un archivo determinado, letra por letra (me gustaría decir "izquierda a derecha", pero estoy lamentablemente se trata de idioma de derecha a izquierda) , como puntos de código Unicode, utilizando sólo herramientas básicas de bash (como vi, less, cat...). ¿Es posible de alguna manera?

Sé que puedo mostrar el archivo en hexadecimal hexdump, pero tendría que volver a calcular los puntos de código. Realmente quiero ver los puntos de código Unicode reales, para poder buscarlos en Google y descubrir qué está sucediendo.

editar: agregaré que no quiero transcodificarlo a una codificación diferente (porque eso es lo que estoy descubriendo en línea). Tengo el archivo en UTF8 y eso está bien. Solo quiero saber los puntos de código exactos de todas las letras.

Karel Bílek
fuente

Respuestas:

5

Me escribí un perl one-liner, que hace exactamente eso, y también imprime el personaje original. (Se espera el archivo de STDIN)

perl -C7 -ne 'for(split(//)){print sprintf("U+%04X", ord)." ".$_."\n"}'

Sin embargo, debería haber una mejor manera que esta.

Karel Bílek
fuente
4

Necesitaba el punto de código para algunos emoticonos comunes, y se me ocurrió esto:

echo -n "😊" |              # -n ignore trailing newline                     \
iconv -f utf8 -t utf32be |  # UTF-32 big-endian happens to be the code point \
xxd -p |                    # -p just give me the plain hex                  \
sed -r 's/^0+/0x/' |        # remove leading 0's, replace with 0x            \
xargs printf 'U+%04X\n'     # pretty print the code point

que imprime

U+1F60A

que es el punto de código para "CARA SONRIENTE CON OJOS SONRIENTES" .

Stefan van den Akker
fuente
2

Inspirado por la respuesta de Neftas , aquí hay una solución un poco más simple que funciona con cadenas, en lugar de un solo carácter:

iconv -f utf8 -t utf32le | hexdump -v -e '8/4 "0x%04x " "\n"' | sed -re"s/0x /   /g"
#                                         ^
# The number `8` above determines the number of columns in the output. Modify as needed.

También hice un script Bash que lee de stdin, o de un archivo, y que muestra el texto original junto con los valores unicode:

COLWIDTH=8
SHOWTEXT=true

tmpfile=$(mktemp)
cp "${1:-/dev/stdin}" "$tmpfile"
left=$(set -o pipefail; iconv -f utf8 -t utf32le "$tmpfile" | hexdump -v -e $COLWIDTH'/4 "0x%05x " "\n"' | sed -re"s/0x /   /g")


if [ $? -gt 0 ]; then
    echo "ERROR: Could not convert input" >&2
elif $SHOWTEXT; then
    right=$(tr [:space:] . < "$tmpfile" | sed -re "s/.{$COLWIDTH}/|&|\n/g" | sed -re "s/^.{1,$((COLWIDTH+1))}\$/|&|/g")
    pr -mts" " <(echo "$left") <(echo "$right")
else
    echo "$left"
fi


rm "$tmpfile"

Salida de muestra

ThomasR
fuente