Wie erhalte ich den ASCII-Wert des Alphabets?
Zum Beispiel 97
für a
?
bash
bash-script
ascii
xmpirate
quelle
quelle
"'A"
richtig ist, während , wenn Sie verwenden"A"
es wird sagen:A: invalid number
. Es scheint, als ob es auf der printf-Seite gemacht wurde (dh in der Shell sind"'A"
es tatsächlich 2 Zeichen, a'
und aA
. Diese werden an printf übergeben. Und im printf-Kontext wird es in den ASCII-Wert von A konvertiert (und wird schließlich gedruckt) als dezimaler Dank an die'%d'
. Verwenden Sie'Ox%x'
, um es in hexa zu zeigen oder'0%o'
um es in oktal zu haben))printf "\\$(printf '%03o' "$1")"
,'%03o'
,LC_CTYPE=C
und das Apostroph in"'$1"
do?Sie können das gesamte Set sehen mit:
Sie erhalten Tabellen in Oktal, Hex und Dezimal.
quelle
Wenn Sie es auf UTF-8-Zeichen erweitern möchten:
Mit
bash
,ksh
oderzsh
builtins:quelle
iceweasel
amDebian sid
. Die von iceweasels Webkonsole bestätigte Schriftart ist "DejaVu Sans" und ich habe ttf-dejavu-dejavu-Kern-ttf-dejavu-Extra-Pakete installiert, die von Debian mit Upstream bei dejavu-fonts.orgctbl()
scheint mir richtig, damit sie angezeigt werden , und die Zeichen aus dem Kopf einer Schnur schneiden mitprintf
, aber es setzt4*((o1=360)>=(d1=240)|(o2=237)>=(d2=159)|(o3=230)>=(d3=152)|(o4=210)>=(d4=136))
in$OPTARG
der Byte - Werte.Das funktioniert gut,
genau gleichbedeutend mit:
quelle
echo -n
unterdrückt nachgestellte Zeilenumbrüche und machttr -d "\n"
echo
, zum Beispiel nicht in Unix-kompatiblen Echos.printf %s A
wäre der tragbare.Ich wähle die einfache (und elegante?) Bash-Lösung:
Für ein Skript können Sie Folgendes verwenden:
Beachten Sie das einfache Anführungszeichen vor dem CharValue. Es ist obligatorisch ...
quelle
printf "%d"
.Der erste
ctbl()
- ganz oben - läuft immer nur einmal. Es wird die folgende Ausgabe generiert (diesed -n l
aus Gründen der Druckbarkeit gefiltert wurde ) :... das sind alle 8-Bit-Bytes (weniger
NUL
) , die in vier in Anführungszeichen gesetzte Zeichenfolgen unterteilt sind, die gleichmäßig an 64-Byte-Grenzen aufgeteilt sind. Die Saiten können dargestellt werden mit Oktal Bereichen wie\200\1-\77
,\100-\177
,\200-\277
,\300-\377
, wo Byte 128 als Platzhalter verwendet wirdNUL
.Der
ctbl()
gesamte Existenzzweck des ersten besteht darin, diese Zeichenfolgen zu generieren, damiteval
die zweitectbl()
Funktion mit ihnen definiert werden kann, die danach buchstäblich eingebettet ist. Auf diese Weise können sie in der Funktion referenziert werden, ohne dass sie jedes Mal neu generiert werden müssen. Wanneval
wird die zweitectbl()
Funktion definiert, hört die erste auf zu sein.Die obere Hälfte der zweiten
ctbl()
Funktion ist hier hauptsächlich nebensächlich - sie dient dazu, jeden aktuellen Shell-Status, den sie beim Aufrufen möglicherweise beeinflusst, portabel und sicher zu serialisieren. In der oberen Schleife werden alle Anführungszeichen in den Werten der Variablen angegeben, die möglicherweise verwendet werden sollen. Anschließend werden alle Ergebnisse in ihren Positionsparametern gestapelt.Die ersten beiden Zeilen geben jedoch sofort 0 zurück und werden auf
$OPTARG
den gleichen Wert gesetzt , wenn das erste Argument der Funktion nicht mindestens ein Zeichen enthält. In diesem Fall schneidet die zweite Zeile das erste Argument sofort auf das erste Zeichen ab, da die Funktion jeweils nur ein Zeichen verarbeitet. Wichtig ist, dass dies im aktuellen Gebietsschemakontext der Fall ist. Wenn ein Zeichen mehr als ein einzelnes Byte enthält, werden, sofern die Shell Multibyte-Zeichen ordnungsgemäß unterstützt, keine Bytes außer denjenigen verworfen, die sich nicht in der befinden erstes Zeichen seines ersten Arguments.Anschließend wird die Sicherungsschleife ausgeführt, sofern dies überhaupt erforderlich ist, und anschließend wird der aktuelle Gebietsschemakontext für jede Kategorie durch Zuweisen zur
LC_ALL
Variablen in das Gebietsschema C neu definiert . Ab diesem Zeitpunkt kann ein Zeichen nur noch aus einem einzigen Byte bestehen. Wenn das erste Zeichen des ersten Arguments mehrere Bytes enthält, sollten diese nun jeweils als einzelne Zeichen für sich adressierbar sein.Aus diesem Grund ist die zweite Hälfte der Funktion im Gegensatz zu einer einzeln ausgeführten Sequenz eine
while
Schleife . In den meisten Fällen wird es wahrscheinlich nur einmal pro Aufruf ausgeführt. Wenn die Shell, in derctbl()
es definiert ist, jedoch Multibyte-Zeichen ordnungsgemäß verarbeitet, wird möglicherweise eine Schleife ausgeführt.Beachten Sie, dass die obige
$(ctbl)
Befehlsersetzung immer nur einmal ausgewertet wird - bis zumeval
Zeitpunkt der erstmaligen Definition der Funktion - und dass das Token für immer durch die Literalausgabe dieser Befehlsersetzung ersetzt wird, die im Speicher der Shell gespeichert ist. Gleiches gilt für die beidencase
Musterbefehlssubstitutionen. Diese Funktion ruft niemals eine Subshell oder einen anderen Befehl auf. Es wird auch niemals versucht, die Eingabe / Ausgabe zu lesen oder zu schreiben (außer im Fall einer Shell-Diagnosemeldung - die wahrscheinlich auf einen Fehler hinweist) .Beachten Sie auch, dass der Test für die Schleifenkontinuität nicht einfach ist
[ -n "$a" ]
, da, wie ich zu meiner Frustration festgestellt habe, einebash
Shell aus irgendeinem Grund Folgendes tut:... und so vergleiche ich
$a
's len explizit mit 0 für jede Iteration, die sich ebenfalls unerklärlicherweise anders verhält (zu lesen: richtig) .Das
case
prüft das erste Byte auf Aufnahme in einen unserer vier Strings und speichert einen Verweis auf das eingestellte Byte$b
. Danach beziehenset
sich die ersten vier Positionsparameter der Shell auf die Zeichenfolgen, die vom Vorgänger der Shell eingebetteteval
und geschrieben wurdenctbl()
.Als nächstes wird alles, was vom ersten Argument übrig bleibt, vorübergehend wieder auf sein erstes Zeichen gekürzt - was nun als ein einzelnes Byte sichergestellt werden sollte. Dieses erste Byte wird als Referenz verwendet, um vom Ende der Zeichenfolge, mit der es übereinstimmt, abzulösen, und die Referenz in
$b
solleval
einen Positionsparameter darstellen, damit alles vom Referenzbyte bis zum letzten Byte in der Zeichenfolge ersetzt werden kann. Die anderen drei Zeichenfolgen werden vollständig aus den Positionsparametern entfernt.An dieser Stelle kann der Wert des Bytes (Modulo 64) als Länge des Strings bezeichnet werden:
Anschließend wird der Modul anhand des Werts in abgeglichen
$b
, das erste Byte in$a
wird dauerhaft entfernt und die Ausgabe für den aktuellen Zyklus wird an einen Stapel angehängt, bis der Vorgang abgeschlossen ist, bevor die Schleife erneut ausgeführt wird, um zu prüfen, ob sie$a
tatsächlich leer ist.Wenn
$a
definitiv leer ist, werden alle Namen und Zustände - mit der Ausnahme$OPTARG
-, dass die während der Ausführung betroffene Funktion in ihrem vorherigen Zustand wiederhergestellt wird - ob gesetzt und nicht null, gesetzt und null oder nicht gesetzt - und die Ausgabe wird gespeichert bis,$OPTARG
wenn die Funktion zurückkehrt. Der tatsächliche Rückgabewert ist eins weniger als die Gesamtzahl der Bytes im ersten Zeichen des ersten Arguments. Jedes einzelne Byte-Zeichen gibt also Null zurück, und jedes Mehrbyte-Zeichen gibt mehr als Null zurück. Das Ausgabeformat ist etwas seltsam.Der Wert
ctbl()
speichert , um$OPTARG
ein gültiges Schal arithmetischer Ausdruck , dass, wenn beurteilt wird , gleichzeitig variable Namen der Formulare festlegen$o1
,$d1
,$o2
,$d2
in dezimalen und oktalen Werten alle entsprechenden Bytes in dem ersten Zeichen des ersten Arguments, aber letztlich auf die Gesamt evaluieren Anzahl der Bytes in seinem ersten Argument. Beim Schreiben hatte ich eine bestimmte Art von Workflow im Sinn, und ich denke, dass eine Demonstration angebracht ist.Ich finde oft einen Grund, eine Saite zu zerlegen
getopts
:Ich mache wahrscheinlich ein bisschen mehr als nur ein Zeichen pro Zeile, aber alles ist möglich. Auf jeden Fall habe ich noch keinen gefunden
getopts
, der das richtig macht (Strike That -dash
dasgetopts
macht char by char, aberbash
definitiv nicht) :Okay. Also habe ich versucht ...
Diese Art von Workflow - Byte für Byte / Zeichen für Zeichen - ist einer, auf den ich häufig stoße, wenn ich ein paar Dinge erledige. Am Anfang der Eingabe müssen Sie die Zeichenwerte kennen, sobald Sie sie lesen, und Sie müssen deren Größe (insbesondere beim Zählen von Spalten) kennen . Außerdem müssen Zeichen ganze Zeichen sein.
Und jetzt habe ich
ctbl()
:Beachten Sie, dass
ctbl()
die$[od][12...]
Variablen nicht wirklich definiert werden - es hat niemals eine dauerhafte Auswirkung auf einen Zustand,$OPTARG
sondern es wird nur die Zeichenfolge eingefügt$OPTARG
, mit der sie definiert werden können. Auf diese Weise erhalte ich die zweite Kopie der obigen Zeichen,printf "\\$o1\\$o2"
weil Sie werden jedes Mal festgelegt, wenn ich eine Bewertung vornehme$(($OPTARG))
. Aber wo ich es mache, deklariere ich auch einen Feldlängenmodifikator fürprintf
das%s
String-Argument-Format. Da der Ausdruck immer die Gesamtzahl der Bytes in einem Zeichen ergibt, erhalte ich das gesamte Zeichen bei der Ausgabe, wenn ich Folgendes mache:quelle
[ "$(printf \\1)" ]|| ! echo but its not null!
Zwischenzeit. Sie können sich besser mit der sinnvollen Kommentarpraxis vertraut machen, es sei denn, Sie empfehlen einen solchen Wettbewerb.sh
Befehlssprache.bash
Es ist wieder einmal ein großer Vorteil derselben und zum großen Teil ein eindrucksvoller Motivator für einen Großteil der Sorgfalt, die oben für weithin tragbare, sich selbst erweiternde und namenspace-ehrenwerte Zeichengrößen jeglicher Art geleistet wurde.bash
sollte bereits viel davon bewältigen, aber diec
Spracheprintf
war und ist möglicherweise mangelhaft die oben bereitgestellten Fähigkeiten.Kein Shell-Skript, funktioniert aber
Beispielausgabe
quelle
konsole
xxd<press enter>
<SHIFT+INSERT><CTRL+D>
du bekommst so etwas wie:
Sie wissen, dass das Symbol, das Sie eingefügt haben, einen Hex-Code hat
0xfb
quelle