パイプで接続したUnicodeコードを印刷しようとしています。
echo 0024 0025 | xargs -n1 echo # one code per line
| xargs printf '\u%s\n'
これを得ることを願っています
$
%
しかし、それは私が得たものです。
printf: missing hexadecimal number in escape
数回の試行錯誤の後、私は実際に2つの小さな質問をしました。一つは理解できる質問で、もう一つは完全に謎のようです。
質問1:
printf '\u%s\n' 0024 0025
私にこれを与える
-bash: printf: missing unicode digit for \u
\u0024
-bash: printf: missing unicode digit for \u
\u0025
質問2:
> # use built-in for $
> printf '\u0024\n'
$
> # use exe for $
> which printf
/usr/bin/printf
> /usr/bin/printf '\u0024\n'
$
> # now use built-in for %
> printf '\u0025\n'
%
> # but look what happens when we use exe for % !!!!
> /usr/bin/printf '\u0025\n'
/usr/bin/printf: invalid universal character name \u0025
(>
forを使用すると出力から見ることができます$
)$
何らかの理由で一部の文字はexeバージョンで動作しますが、一部の文字はそうではありません。ただし、すべての文字は組み込みのprintfで動作します。
したがって、問題#2以外の場合に機能できる解決策は次のとおりです(ただし、元のアイデアよりはるかに遅くなる可能性があります)。
echo 0024 0025 | xargs -n1 echo # one item per line
| xargs -I {} printf '\u{}\n'
ただし、問題#2のため、作業の半分しか実行されません。
$ echo 0024 0025 | xargs -n1 echo | xargs -I {} printf '\u{}\n'
$
printf: invalid universal character name \u0025
($は出ますが、%はエラーです)
だから私の質問は次のとおりです。
- 各引数に対して1回ではなく1回だけprintfを実行できるようにprintfに数値コードを使用させる方法はありますか-I
?
printf
- 組み込み機能は気にしませんが、printf
exeは気に入らませんが、%
私は何を間違っていますか$
?
答え1
二重拡張の問題(\u
以前に処理された)を回避するには、少なくともBashでを%s
使用できます。%b
printf
printf '%b\n' \\u0024 \\u0025
さまざまな方法で入力を前処理できます。
set 0024 0025
printf '%b\n' "${@/#/\\u}"
離れたprintf
、GNU coreutilsで実装、Unicode文字仕様には次の制限があります。
printf
ISO C 99で導入された2つの文字構文を説明してください。 '\u
'は、4つの16進数で指定された16ビットUnicode(ISO / IEC 10646)文字を表します。ヘヘ、 '\U
'は、8桁の16進数で指定された32ビットUnicode文字を表します。はははは。 Unicode文字はロケール設定printf
に従って出力されます。LC_CTYPE
この構文は、U+0024($)、U+0040(@)、U+0060(`) を除いて U+0000… U+009F、U+D800… U + DFFF範囲のUnicode文字を指定できません。
これがなぜこのように生産できないのかを説明します%
。
答え2
エスケープシーケンスは標準printf
ユーティリティではサポートされていません\uxxxx
。以下を参照してください。https://pubs.opengroup.org/onlinepubs/9699919799/utilities/printf.html
これは一部の実装(組み込みなどksh
)に存在する可能性のある拡張機能によって異なりますが、普遍的なサポートは期待できないとします。標準文書を参照してくださいprintf
。
もう一つの問題は、あなたが電話していると仮定しているようです
printf '\u%s\n' 123
以下を呼び出すのと同じ結果が生成されます。
printf '\u123\n'
printf
書式文字列は要素ごとに解析されるため動作しませんが、予想される書式文字列は表示されません。
bash
したがって、これを使用してスクリプトを実行しても、\uxx
バックスラッシュエスケープの後に2つの16進数があり、エスケープシーケンスが形式文字列に文字通り表示されると、バックスラッシュエスケープが拡張されると予想できます。 4 つの 16 進数を拡張するには、\Uxxxx
書式文字列で文字通り拡張する必要があります。