コマンドラインでファイル名をデコードすることは可能ですか?
次の2つのファイルがあるとします。
ファイル名をUTF-8値にデコードするコマンドラインツールはありますか。
16進数としてバイト値を取得する標準(POSIX/Unix)コマンドはod
です。
file=foo.mp3
printf %s "$file" | od -An -vtx1
次のような出力が得られます。
66 6f 6f 2e 6d 70 33
上記の$file
には、(zsh
以外のシェルの非NUL)bytesの任意の配列が含まれています。文字コードは考慮に入らない。
$file
に文字の配列を含める(ロケールのエンコーディングに含まれる)必要があり、リトルエンディアンでそれぞれのUnicodeコードポイントを16進数として取得する場合システム、あなたがすることができます:
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エンコードの16進数としてバイト値が必要な場合:
printf %s "$file" | iconv -t UTF-8 | od -An -vtx1
ASCII文字のみを含むfoo.mp3
のようなものの場合、それらはすべて同等になります。
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
プレーンBashの場合:
a=abcdefghij
for ((i=0;i<${#a};i++));do printf %02X \'${a:$i:1};done
6162636465666768696A
ニーズに合わせてprintf
形式をカスタマイズします。
これは単純なPerlスクリプトで実行できると思います。
_Perl -we 'foreach my $file (glob("*")) {
printf "0x%02X ", ord($_) foreach split//, $file; print "\n" }; '
_
ディレクトリにファイル_foo.mp3
_および_bar.mp3
_が含まれている場合、結果はyoursと同様になります。
_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
の読み取りに伴うものであり、ファイル名を別の行に区切るのは困難です。