文字列から文字を収集し、対応するUnicodeを印刷します。

文字列から文字を収集し、対応するUnicodeを印刷します。

コンテキスト(気にしない場合はスキップしてください。私が完全に間違っているようであれば、読んでください。)

メモリが小さい組み込みシステムでは、実際に必要なグリフだけを含むフォントを作成したいと思います。そのため、ビルド時に言語ファイルをスキャンして文字列から文字を抽出し、そのコードをフォント生成ツールの引数として使用する必要があります。

関連文字列を含む翻訳ファイル(もちろんこれは単なる例ですが、少なくともいくつかのUnicodeの内容を扱います。)

TEXT_1=Foo
TEXT_2=Bar
TEXT_3=Baz
TEXT_4=Ünicødé
TEXT_5=ελληνικά

期待される出力

0x42,0x61,0x72,0x42,0x61,0x7A,0x46,0x6F,0x6F,0xDC,0x6E,0x69,0x63,0xF8,0x64,0xE9,0x3B5,0x3BB,0x3BB,0x3B7,0x3BD,0x3B9,0x3BA,0x3AC

これまでの私のアプローチ

スクリプトは私が説明したことを行います。つまり、sedファイルを読み込み、文字列を抽出し、書式を設定する準備をしprintfsort -u重複項目を削除します。

for char in $(sed "s/[^=]*=//;s/./'& /g" myLang.translation|sort -u); do
  printf "0x%02X\n" $char
done

この例では動作しますが、実際のファイルでは醜く信頼できず、バグがあり、遅くなる可能性があります。したがって、より良いツール、より良いアプローチ、より良いものを指定できますか?

ベストアンサー1

そしてperl

perl -C -lne '
  if (/=(.*)/) {$c{$_}++ for split //, $1}
  END{print join ",", map {sprintf "0x%X", ord$_} sort keys %c}
  ' your-file

以下を提供します。

0x42,0x46,0x61,0x63,0x64,0x69,0x6E,0x6F,0x72,0x7A,0xDC,0xE9,0xF8,0x3AC,0x3B5,0x3B7,0x3B9,0x3BA,0x3BB,0x3BD
  • -CロケールがUTF-8を文字マップとして使用している場合は、UTF-8 I / Oを実行してください。
  • -ln sed -n各入力行でコードが実行されるモードです。-l入力から行区切り文字を削除し、出力に再度追加します(実行$\ = $/)。
  • -e 'code'スクリプトではなくコマンドラインで実行するコードを指定します。
  • /=(.*)/一致させる行には、1つ以上のキャプチャ(最初のキャプチャグループ)=が最初に発生した後の内容が含まれます。$1
  • split //, $1空の区切り文字を使用して単一の文字に分割します。
  • $c{$_}++ for that-above文字リストを繰り返し、対応する連想配列要素を増やします。%c文字をその項目にマップします。ここではその数を使用しません。
  • END{code}code最後まで実行するだけです。
  • sort keys %cこの連想配列のキーを語彙的にソートします。
  • map { code } @list各要素にコードを適用してリストを変換します。
  • ord$_文字の数値を取得します。
  • sprintf "0x%X"16進数(大文字ABCDEF、小文字0x)でフォーマットします。
  • join ",", @listリストに追加,
  • print印刷してから$\(改行)を入力してください。

zshでは(おそらくはるかに効率が悪いでしょう):

$ set -o cbases -o extendedglob
$ LC_COLLATE=C
$ echo ${(j[,])${(ous[])"$(<your-file cut -sd= -f2- | tr -d '\n')"}/(#m)?/$(([#16]#MATCH))}
0x42,0x46,0x61,0x63,0x64,0x69,0x6E,0x6F,0x72,0x7A,0xDC,0xE9,0xF8,0x3AC,0x3B5,0x3B7,0x3B9,0x3BA,0x3BB,0x3BD

または外部ユーティリティを使用せずに:

$ set -o cbases -o extendedglob
$ LC_COLLATE=C
$ echo ${(j[,])${(@ous[])${(f)"$(<your-file)"}#*=}/(#m)?/$(([#16]#MATCH))}
0x42,0x46,0x61,0x63,0x64,0x69,0x6E,0x6F,0x72,0x7A,0xDC,0xE9,0xF8,0x3AC,0x3B5,0x3B7,0x3B9,0x3BA,0x3BB,0x3BD
  • "$(<you-file)"IFS で区切られないように末尾の改行を削除し、引用符で囲まれたファイルの内容
  • ${(f)param}行に分割しfて行をリストにインポートします。
  • ${array#*=}*=配列要素の最短先行部分一致を削除します。
  • @保証するためのフラグ リスト処理
  • o語彙順(Cロケールのコードポイント基準)
  • unique 重複排除
  • s[]別の文字に分割します。
  • ${array/(#m)?/$(([#16]#MATCH))}監査()でキャプチャされた文字を?16進形式の値(算術式で)に置き換えます。このオプションを使用すると、次のことができます。$MATCH(#m)#MATCH[#16]cbases0xBEEF16#BEEF
  • j[,]に参加してください,

これを別々の段階に分けると、より明確になります。

set -o cbases -o extendedglob
LC_COLLATE=C
contents=$(<your-file)
lines=( ${(f)contents} )
values=( ${lines#*=} )
chars=( ${(@ous[])values} )
codepoints=( ${chars/(#m)?/$(( [#16] #MATCH ))} )
echo ${(j[,])codepoints}

おすすめ記事