Стандартная команда (POSIX / Unix) для получения байтовых значений в виде шестнадцатеричных чисел - od
.
file=foo.mp3
printf %s "$file" | od -An -vtx1
Что дает результат, аналогичный следующему:
66 6f 6f 2e 6d 70 33
$ file
выше содержит произвольный массив (отличных от NUL для оболочек, отличных от zsh
) байтов . Кодировка символов не рассматривается.
Если вы хотите, чтобы $ file
содержал массив из символов (в кодировке локали), и вы хотите получить кодовые точки Unicode для каждого из них в виде шестнадцатеричных чисел, в системе Little-Endian вы можете:
printf %s "$file" | iconv -t UTF-32LE | od -An -vtx4
См. также:
printf %s "$file" | recode ..dump
Или:
printf %s "$file" | uconv -x hex/unicode
printf %s "$file" | uconv -x '([:Any:])>&hex/unicode($1)\n'
Если вам нужны значения байтов как шестнадцатеричные числа в кодировке UTF-8 этих символов:
printf %s "$file" | iconv -t UTF-8 | od -An -vtx1
Для чего-то вроде foo.mp3
, который содержит только символы ASCII, все они будут эквивалентны.
Я думаю, что это можно сделать с помощью простого Perl-скрипта:
perl -we 'foreach my $file (glob("*")) {
printf "0x%02X ", ord($_) foreach split//, $file; print "\n" }; '
, что приведет к выводу, аналогичному вашему, когда каталог содержит файлы foo.mp3
и bar.mp3
:
0x62 0x61 0x72 0x2E 0x6D 0x70 0x33
0x66 0x6F 0x6F 0x2E 0x6D 0x70 0x33
(я думаю, glob ()
сортирует имена.)
Пояснение:
foreach my $file (glob("*")) { # loop over all filenames in current directory
printf "0x%02X ", ord($_) # take the character as a number, and print in hex
foreach split//, $file; # .. after splitting the filename to characters
print "\n"; # add a newline
}
(* кроме тех, которые начинаются с точки)
Это просто напечатает фактические байты в именах файлов, поскольку они хранятся в файловой системе. Если у вас есть файлы, имена которых не в UTF-8, скрипт не преобразует их.
Вы также можете сделать что-то вроде конвейерной передачи вывода ls
в od
или xxd
, которые также будут работать с другими данными, кроме списков имен файлов, но вызовет все проблемы , возникающие при чтении ls
, и будет трудно разделить имена файлов по разным строкам.
С обычным Bash:
a=abcdefghij
for ((i=0;i<${#a};i++));do printf %02X \'${a:$i:1};done
6162636465666768696A
Настройте printf
формат в соответствии с вашими потребностями.
С perl
:
$ perl -CA -le 'print join " ", map { sprintf "0x%X", $_ } unpack "U*" for @ARGV' \
foo.mp3 bar.mp3 cường
0x66 0x6F 0x6F 0x2E 0x6D 0x70 0x33
0x62 0x61 0x72 0x2E 0x6D 0x70 0x33
0x63 0x1B0 0x1EDD 0x6E 0x67
Если вы сохраняете этот список имен файлов в файле, то:
perl -CI -lne 'print join " ", map { sprintf "0x%X", $_ } unpack "U*"' <file