Zobacz kody Unicode dla wszystkich liter w pliku na bash

11

Mam do czynienia z plikiem, który ma wiele niewidocznych znaków kontrolnych, takich jak „od prawej do lewej” lub „non-joiner o zerowej szerokości”, inne spacje niż normalne spacje i tak dalej, i mam z tym problem.

Teraz chciałbym jakoś wyświetlić wszystkie litery w danym pliku, litera po literze (chciałbym powiedzieć „od lewej do prawej”, ale niestety mam do czynienia z językiem od prawej do lewej)) , jako punkty kodowe Unicode, używając tylko podstawowe narzędzia bash (jak vi, less, cat...). Czy to jest jakoś możliwe?

Wiem, że mogę wyświetlić plik w systemie szesnastkowym hexdump, ale musiałbym ponownie obliczyć punkty kodowe. Naprawdę chcę zobaczyć rzeczywiste punkty kodowe Unicode, więc mogę je wyszukiwać w Google i sprawdzać, co się dzieje.

edytuj: Dodam, że nie chcę transkodować na inne kodowanie (bo tego właśnie dowiaduję się online). Mam plik w UTF8 i jest w porządku. Chcę tylko znać dokładne współrzędne wszystkich liter.

Karel Bílek
źródło

Odpowiedzi:

6

Napisałem sobie perlową linijkę, która właśnie to robi, a także drukuje oryginalny znak. (Oczekuje pliku od STDIN)

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

Jednak powinien istnieć lepszy sposób niż ten.

Karel Bílek
źródło
Tak, działa i potrzebujemy tego polecenia
Yan King Yin
5

Potrzebowałem punktu kodowego dla niektórych typowych emotikonów i wymyśliłem:

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

który drukuje

U+1F60A

który jest punktem kodowym dla „UŚMIECHAJĄCE SIĘ TWARZEM Z UŚMIECHOWANYMI OCZAMI” .

Stefan van den Akker
źródło
3

Zainspirowany odpowiedzią Neftasa , oto nieco prostsze rozwiązanie, które działa z łańcuchami, a nie z pojedynczym znakiem:

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.

Stworzyłem również skrypt Bash, który czyta ze standardowego wejścia lub z pliku i wyświetla oryginalny tekst wraz z wartościami 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"

Próbka wyjściowa

ThomasR
źródło