
Ich versuche, einige Unicode-Codes auszudrucken, die ich so einleite
echo 0024 0025 | xargs -n1 echo # one code per line
| xargs printf '\u%s\n'
hoffe, dies zu bekommen
$
%
aber das ist, was ich bekomme
printf: missing hexadecimal number in escape
Nach einigem Herumprobieren habe ich tatsächlich zwei kleinere Probleme, eines ergibt irgendwie Sinn, das andere scheint ein komplettes Rätsel zu sein.
Problem 1:
printf '\u%s\n' 0024 0025
gibt mir das
-bash: printf: missing unicode digit for \u
\u0024
-bash: printf: missing unicode digit for \u
\u0025
Problem 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
(verwenden Sie >
„for“ , damit Sie es in der Ausgabe $
sehen können )$
Aus irgendeinem Grund funktionieren einige Zeichen mit der EXE-Version, andere jedoch nicht, obwohl alle mit dem integrierten Printf funktionieren.
hier ist also ein Workaround, der funktionieren würde, wenn es Problem Nr. 2 nicht gäbe (aber möglicherweise deutlich langsamer wäre als meine ursprüngliche Idee)
echo 0024 0025 | xargs -n1 echo # one item per line
| xargs -I {} printf '\u{}\n'
aber aufgrund von Problem Nr. 2 funktioniert es nur halb:
$ echo 0024 0025 | xargs -n1 echo | xargs -I {} printf '\u{}\n'
$
printf: invalid universal character name \u0025
($ kommt heraus, aber % bringt einen Fehler)
Meine Fragen lauten also:
-Gibt es eine Möglichkeit, printf mit dem Zahlencode zum Laufen zu bringen, sodass ich printf einmal ausführen kann, anstatt einmal pro Argument mit -I
?
-Was mache ich falsch, dass es dem printf
integrierten Programm nichts ausmacht, printf
der exe aber nicht gefällt, aber nur für %
und nicht für $
?
Antwort1
Um das Problem der doppelten Erweiterung ( \u
wird vor verarbeitet %s
) zu vermeiden, können Sie %b
zumindest in Bash Folgendes verwenden printf
:
printf '%b\n' \\u0024 \\u0025
Sie können Ihre Eingaben auf verschiedene Arten vorverarbeiten:
set 0024 0025
printf '%b\n' "${@/#/\\u}"
Der printf
eigenständigewie in GNU Coreutils implementiert, unterliegt den folgenden Einschränkungen hinsichtlich Unicode-Zeichenspezifikationen:
printf
interpretiert zwei in ISO C 99 eingeführte Zeichensyntaxen: '\u
' für 16-Bit Unicode (ISO/IEC 10646) Zeichen, angegeben als vier hexadezimale Ziffernhhhhund '\U
' für 32-Bit-Unicode-Zeichen, angegeben als acht hexadezimale Ziffernhhhhhhhh.printf
gibt die Unicode-Zeichen entsprechend derLC_CTYPE
Ländereinstellung aus. Unicode-Zeichen in den Bereichen U+0000…U+009F, U+D800…U+DFFF können mit dieser Syntax nicht angegeben werden, mit Ausnahme von U+0024 ($), U+0040 (@) und U+0060 (`).
%
Dies erklärt, warum Sie auf diese Weise nicht produzieren können .
Antwort2
Das Standarddienstprogramm printf
unterstützt keine \uxxxx
Escape-Sequenzen, siehe:https://pubs.opengroup.org/onlinepubs/9699919799/utilities/printf.html
Die Annahme, dass dies funktionieren könnte, hängt von Erweiterungen ab, die in einigen Implementierungen (z. B. in einem ksh
integrierten) vorhanden sein können, von denen jedoch nicht erwartet werden kann, dass sie allgemein unterstützt werden. Siehe das printf
Standarddokument.
Ein weiteres Problem scheint Ihre Annahme zu sein, dass der Aufruf
printf '\u%s\n' 123
würde zum selben Ergebnis führen wie der Aufruf von:
printf '\u123\n'
Dies funktioniert nicht, da printf
die Formatzeichenfolge Element für Element analysiert wird und die erwartete Formatzeichenfolge nicht angezeigt wird.
Selbst wenn Sie also bash
zur Ausführung des Skripts verwenden, können Sie erwarten, dass der \uxx
Backslash-Escape erweitert wird, wenn zwei Hexadezimalziffern folgen und die Escape-Sequenz wörtlich in der Formatzeichenfolge vorkommt. Wenn Sie 4 Hexadezimalziffern erweitert haben möchten, müssen Sie wörtlich in der Formatzeichenfolge vorkommen \Uxxxx
.