¿Cómo obtengo el valor ASCII del alfabeto?
Por ejemplo, 97
para a
?
bash
bash-script
ascii
xmpirato
fuente
fuente
"'A"
es correcta, mientras que si se utiliza"A"
dirá:A: invalid number
. Parece que está hecho en el lado printf (es decir, en el shell, de"'A"
hecho hay 2 caracteres, ay'
aA
. Esos se pasan a printf. Y en el contexto printf, se convierte al valor ascii de A, (y finalmente se imprime como decimal gracias a'%d'
. Úselo'Ox%x'
para mostrarlo en hexa o'0%o'
para tenerlo en octal))printf "\\$(printf '%03o' "$1")"
,'%03o'
,LC_CTYPE=C
y la comilla simple en"'$1"
Do?Puedes ver todo el conjunto con:
Obtendrá tablas en octal, hexadecimal y decimal.
fuente
Si desea extenderlo a los caracteres UTF-8:
Con
bash
,ksh
ozsh
las órdenes internas:fuente
iceweasel
enDebian sid
. La fuente confirmada por la consola web de iceweasel es "DejaVu Sans" y tengo instalados los paquetes ttf-dejavu ttf-dejavu-core ttf-dejavu-extra que provienen de Debian con upstream en dejavu-fonts.orgctbl()
me parece activar adecuadamente para mostrarla, y para cortar el carbón de leña de la cabeza de una cadena conprintf
, sino que pone4*((o1=360)>=(d1=240)|(o2=237)>=(d2=159)|(o3=230)>=(d3=152)|(o4=210)>=(d4=136))
en$OPTARG
los valores de bytes.Esto funciona bien
exactamente equivalente a:
fuente
echo -n
suprime la nueva línea final eliminando la necesidad detr -d "\n"
echo
, no en ecos compatibles con Unix, por ejemplo.printf %s A
Sería el portátil.Voy por la solución Bash simple (y elegante?):
En un script puedes usar lo siguiente:
Observe la comilla simple antes de CharValue. Está obligado ...
fuente
printf "%d"
.El primero
ctbl()
, en la parte superior, solo se ejecuta una vez. Genera el siguiente resultado (que se ha filtrado a travéssed -n l
de la capacidad de impresión) :... que son todos bytes de 8 bits (menos
NUL
) , divididos en cuatro cadenas entre comillas divididas de manera uniforme en los límites de 64 bytes. Las cuerdas pueden ser representados con rangos octales gusta\200\1-\77
,\100-\177
,\200-\277
,\300-\377
, donde byte 128 se utiliza como un lugar-soporte paraNUL
.El primer
ctbl()
propósito de la existencia del primero es generar esas cadenas para queeval
puedan definir la segundactbl()
función con ellas literalmente incrustadas a partir de entonces. De ese modo, se puede hacer referencia a ellos en la función sin necesidad de generarlos nuevamente cada vez que se necesiten. Cuandoeval
define la segundactbl()
función, la primera dejará de ser.La mitad superior de la segunda
ctbl()
función es principalmente auxiliar aquí: está diseñada para serializar de forma portátil y segura cualquier estado de shell actual que pueda afectar cuando se llama. El bucle superior citará las comillas en los valores de cualquier variable que quiera usar, y luego apilará todos los resultados en sus parámetros posicionales.Sin embargo, las dos primeras líneas devuelven inmediatamente 0 y se establecen
$OPTARG
en el mismo si el primer argumento de la función no contiene al menos un carácter. Y si lo hace, la segunda línea trunca inmediatamente su primer argumento solo a su primer carácter, porque la función solo maneja un carácter a la vez. Es importante destacar que hace esto en el contexto local actual, lo que significa que si un carácter puede comprender más de un byte, entonces, siempre que el shell admita caracteres de varios bytes, no descartará ningún byte excepto aquellos que no están en el primer personaje de su primer argumento.Luego realiza el ciclo de guardar si es necesario, y luego redefine el contexto de la configuración regional actual a la configuración regional C para cada categoría mediante la asignación a la
LC_ALL
variable. A partir de este momento, un carácter solo puede consistir en un solo byte, por lo que si hubiera varios bytes en el primer carácter de su primer argumento, ahora estos deberían ser direccionables como caracteres individuales por derecho propio.Es por esta razón que la segunda mitad de la función es un
while
bucle , a diferencia de una secuencia de ejecución individual. En la mayoría de los casos, probablemente se ejecutará solo una vez por llamada, pero, si el shell en el quectbl()
se define correctamente maneja los caracteres de varios bytes, podría repetirse.Tenga en cuenta que la anterior
$(ctbl)
sustitución comando sólo se evalúa una vez cada vez - poreval
cuando la función se define inicialmente - y que siempre después de que el distintivo se sustituye por la salida literal de que la sustitución de comandos como guarda en la memoria de la cáscara. Lo mismo es cierto para las doscase
sustituciones de comando de patrón. Esta función nunca llama a un subshell ni a ningún otro comando. Tampoco intentará leer o escribir entradas / salidas (excepto en el caso de algún mensaje de diagnóstico de shell, que probablemente indica un error) .También tenga en cuenta que la prueba de continuidad del bucle no es simplemente
[ -n "$a" ]
, porque, como descubrí para mi frustración, por alguna razón unbash
shell lo hace:... y entonces comparo explícitamente
$a
len a 0 para cada iteración, que, también inexplicablemente, se comporta de manera diferente (léase: correctamente) .Los
case
cheques el primer byte para su inclusión en cualquiera de nuestros cuatro cuerdas y almacena una referencia al conjunto del byte$b
. Luego, los primeros cuatro parámetros posicionales del shell sonset
las cadenas incrustadaseval
y escritas porctbl()
el predecesor.A continuación, lo que queda del primer argumento se vuelve a truncar temporalmente a su primer carácter, que ahora debe asegurarse de que sea un solo byte. Este primer byte se utiliza como una referencia a la tira de la cola de la cadena de la que corresponde y la referencia en
$b
estáeval
'd para representar un parámetro de posición de modo de todo, desde el byte de referencia al último byte en la cadena puede ser sustituido de distancia. Las otras tres cadenas se eliminan completamente de los parámetros posicionales.En este punto, el valor del byte (módulo 64) puede referenciarse como el len de la cadena:
Luego se hace un poco de matemática para conciliar el módulo en función del valor
$b
, el primer byte$a
se elimina permanentemente y la salida para el ciclo actual se agrega a una pila hasta que se complete antes de que el ciclo se recicle para verificar si$a
está realmente vacío.Cuando
$a
definitivamente está vacío, todos los nombres y estados, con la excepción de$OPTARG
que la función afectada a lo largo de su ejecución se restaura a su estado anterior, ya sea establecido y no nulo, establecido y nulo o sin establecer, y la salida se guarda a$OPTARG
como vuelve la función. El valor de retorno real es uno menos que el número total de bytes en el primer carácter de su primer argumento, por lo que cualquier carácter de un solo byte devuelve cero y cualquier carácter de varios bytes devolverá más de cero, y su formato de salida es un poco extraño.El valor
ctbl()
se guarda en$OPTARG
una cáscara de expresión aritmética válido que, si se evalúa, fijará al mismo tiempo los nombres de variables de las formas$o1
,$d1
,$o2
,$d2
al decimal y los valores octales de todos los bytes respectivos en el primer carácter de su primer argumento, pero en última instancia evaluar al total número de bytes en su primer argumento. Tenía un tipo específico de flujo de trabajo en mente al escribir esto, y creo que tal vez sea necesario hacer una demostración.A menudo encuentro una razón para separar una cadena con
getopts
like:Probablemente haga un poco más que imprimirlo en un carácter por línea, pero todo es posible. En cualquier caso, todavía no he encontrado una
getopts
que va a hacer correctamente (huelga que -dash
Esgetopts
lo hace charla por char, perobash
definitivamente no lo hace) :Okay. Entonces intenté ...
Ese tipo de flujo de trabajo, el byte para byte / char para char kind, es uno en el que a menudo me meto cuando hago cosas de tty. En la vanguardia de la entrada, debe conocer los valores de caracteres tan pronto como los lea, y necesita sus tamaños (especialmente al contar columnas) , y necesita que los caracteres sean caracteres enteros .
Y ahora tengo
ctbl()
:Tenga en cuenta que en
ctbl()
realidad no define las$[od][12...]
variables, nunca tiene un efecto duradero en ningún estado$OPTARG
, pero solo coloca la cadena$OPTARG
que se puede usar para definirlas, que es la forma en que obtengo la segunda copia de cada carácter anteriorprintf "\\$o1\\$o2"
porque se establecen cada vez que evalúo$(($OPTARG))
. Pero cuando lo hago también estoy declarando un modificador de la longitud del campo deprintf
's%s
formato argumento de cadena, y debido a la expresión da siempre como resultado el número total de bytes de un personaje, me sale todo el carácter en la salida cuando lo haga:fuente
[ "$(printf \\1)" ]|| ! echo but its not null!
mientras tanto, siéntase libre de familiarizarse mejor con la práctica de comentarios significativos, a menos que recomiende un concurso real de este tipo ...?sh
lenguaje de comando POSIX .bash
es un bourne nuevamente superior de lo mismo, y en gran parte un motivador precipitado para gran parte de la atención brindada anteriormente hacia tamaños de caracteres honorables de gran tamaño, portátiles y autoexpandibles de cualquier tipo.bash
ya debería manejar gran parte de esto, pero elc
lenguajeprintf
era, y tal vez es, deficiente la capacidad proporcionada anteriormente.No es un script de shell, pero funciona
Salida de muestra
fuente
konsole
xxd<press enter>
<SHIFT+INSERT><CTRL+D>
obtienes algo como:
sabes que el símbolo que pegaste tiene código hexadecimal
0xfb
fuente