Como obtenho o valor ASCII do alfabeto?
Por exemplo, 97
para a
?
bash
bash-script
ascii
xmpirate
fonte
fonte
"'A"
está correto enquanto que se usar"A"
, ele vai dizer:A: invalid number
. Parece que é feito no lado printf (ou seja, no shell,"'A"
é de fato 2 caracteres, a'
e aA
. Esses são passados para printf. E, no contexto printf, é convertido no valor ascii de A (e é finalmente impresso como decimal, graças a'%d'
. Use'Ox%x'
para mostrá-lo em hexa ou'0%o'
em octal))printf "\\$(printf '%03o' "$1")"
,'%03o'
,LC_CTYPE=C
ea única citação em"'$1"
tarefas?Você pode ver o conjunto inteiro com:
Você receberá tabelas em octal, hex e decimal.
fonte
Se você deseja estendê-lo para caracteres UTF-8:
Com
bash
,ksh
ouzsh
builtins:fonte
iceweasel
onDebian sid
. A fonte confirmada pelo console da web do iceweasel é "DejaVu Sans" e eu tenho os pacotes ttf-dejavu ttf-dejavu-core ttf-dejavu-extra instalados que vêm do Debian com upstream em dejavu-fonts.orgctbl()
me parece permitir corretamente para exibi-lo, e para cortar o caractere da cabeça de uma cadeia comprintf
, mas põe4*((o1=360)>=(d1=240)|(o2=237)>=(d2=159)|(o3=230)>=(d3=152)|(o4=210)>=(d4=136))
em$OPTARG
para os valores de byte.Isso funciona bem,
exatamente equivalente a:
fonte
echo -n
suprime de arrasto nova linha eliminando a necessidade detr -d "\n"
echo
, não em ecos compatíveis com Unix, por exemplo.printf %s A
seria o portátil.Estou optando pela solução Bash simples (e elegante?):
Para em um script você pode usar o seguinte:
Observe a aspas simples antes do CharValue. É obrigatório ...
fonte
printf "%d"
.O primeiro
ctbl()
- no topo - apenas funciona uma vez. Ele gera a seguinte saída (que foi filtradased -n l
para fins de impressão) :... que são todos os bytes de 8 bits (menos
NUL
) , divididos em quatro cadeias de caracteres entre aspas, divididas igualmente nos limites de 64 bytes. As cordas podem ser representados com faixas octal gosto\200\1-\77
,\100-\177
,\200-\277
,\300-\377
, na qual o byte 128 é utilizada como um espaço reservado paraNUL
.O primeiro
ctbl()
objetivo da existência é gerar essas strings para queeval
possam definir a segundactbl()
função com elas literalmente incorporadas posteriormente. Dessa forma, eles podem ser referenciados na função sem precisar gerá-los novamente cada vez que forem necessários. Quandoeval
define a segundactbl()
função, a primeira deixará de existir.A metade superior da segunda
ctbl()
função é principalmente auxiliar aqui - ela foi projetada para serializar com segurança e portabilidade qualquer estado atual do shell que possa afetar quando for chamado. O loop superior citará quaisquer aspas nos valores de quaisquer variáveis que ele queira usar e, em seguida, empilhará todos os resultados em seus parâmetros posicionais.As duas primeiras linhas, no entanto, retornam 0 imediatamente e são definidas
$OPTARG
como iguais se o primeiro argumento da função não contiver pelo menos um caractere. E se isso acontecer, a segunda linha imediatamente trunca seu primeiro argumento apenas para seu primeiro caractere - porque a função lida apenas com um caractere de cada vez. É importante ressaltar que isso é feito no contexto de localidade atual, o que significa que, se um caractere puder incluir mais de um byte, então, desde que o shell suporte adequadamente caracteres de vários bytes, ele não descartará nenhum bytes, exceto aqueles que não estão no primeiro caractere de seu primeiro argumento.Em seguida, ele executa o loop de salvamento, se for necessário, e depois redefine o contexto de local atual para o local C para cada categoria, atribuindo à
LC_ALL
variável. Desse ponto em diante, um caractere pode consistir apenas em um único byte; portanto, se houver vários bytes no primeiro caractere de seu primeiro argumento, agora eles deverão ser endereçáveis como caracteres individuais.É por esse motivo que a segunda metade da função é um
while
loop , em oposição a uma sequência de execução individual. Na maioria dos casos, provavelmente será executado apenas uma vez por chamada, mas, se o shellctbl()
definido corretamente manipular adequadamente caracteres de vários bytes, ele poderá executar um loop.Observe que a
$(ctbl)
substituição do comando acima é avaliada apenas uma vez -eval
quando a função é definida inicialmente - e que para sempre após esse token é substituída pela saída literal da substituição do comando, salva na memória do shell. O mesmo vale para as duascase
substituições de comando padrão. Essa função nunca chama um subshell ou qualquer outro comando. Também nunca tentará ler ou gravar entrada / saída (exceto no caso de alguma mensagem de diagnóstico do shell - o que provavelmente indica um erro) .Observe também que o teste para continuidade de loop não é simplesmente
[ -n "$a" ]
porque, como descobri minha frustração, por algum motivo umbash
shell faz:... e, por isso, comparo explicitamente
$a
len a 0 para cada iteração, que, também inexplicavelmente, se comporta de maneira diferente (leia-se: corretamente) .Ele
case
verifica o primeiro byte para inclusão em qualquer uma das quatro seqüências de caracteres e armazena uma referência ao conjunto de bytes$b
. Posteriormente, os quatro primeiros parâmetros posicionais do shell sãoset
para as cadeias incorporadaseval
e escritas peloctbl()
predecessor.Em seguida, tudo o que resta do primeiro argumento é novamente temporariamente truncado para seu primeiro caractere - que agora deve ser garantido como um único byte. Esse primeiro byte é usado como referência para retirar a cauda da string com a qual correspondeu e a referência
$b
éeval
para representar um parâmetro posicional, para que tudo, desde o byte de referência até o último byte na string, possa ser substituído. As outras três strings são retiradas inteiramente dos parâmetros posicionais.Nesse ponto, o valor do byte (módulo 64) pode ser referenciado como len da string:
Um pouco de matemática é feito para reconciliar o módulo com base no valor em
$b
, o primeiro byte$a
é permanentemente removido e a saída do ciclo atual é anexada a uma pilha pendente de conclusão antes que o loop seja reciclado para verificar se$a
está realmente vazio.Quando
$a
definitivamente está vazio, todos os nomes e estados - com exceção de$OPTARG
- que a função afetada ao longo de sua execução são restaurados ao estado anterior - definidos e não nulos, definidos e nulos ou não definidos - e a saída é salva para$OPTARG
quando a função retornar. O valor de retorno real é um a menos do que o número total de bytes no primeiro caractere de seu primeiro argumento - portanto, qualquer caractere de byte único retorna zero e qualquer caractere de vários bytes retornará mais de zero - e seu formato de saída é um pouco estranho.O valor
ctbl()
salva em$OPTARG
uma expressão aritmética shell válido que, se avaliado, irá simultaneamente definir nomes de variáveis das formas$o1
,$d1
,$o2
,$d2
para decimal e os valores octais de todos os respectivos bytes no primeiro caractere de seu primeiro argumento, mas em última análise avaliar ao total número de bytes em seu primeiro argumento. Eu tinha um tipo específico de fluxo de trabalho em mente ao escrever isso e acho que talvez uma demonstração esteja em ordem.Costumo encontrar um motivo para separar uma string com o seguinte
getopts
:Provavelmente faço um pouco mais do que apenas imprimir um caractere por linha, mas tudo é possível. Em qualquer caso, eu ainda não encontrei um
getopts
que vai fazer corretamente (greve que -dash
égetopts
o faz carbonizar por char, masbash
definitivamente não) :Está bem. Então eu tentei ...
Esse tipo de fluxo de trabalho - o byte por byte / char para o tipo char - é aquele em que geralmente entro ao fazer coisas tty. Na extremidade principal da entrada, você precisa conhecer os valores de caracteres assim que os ler, e os tamanhos (principalmente ao contar colunas) , e os caracteres para serem caracteres inteiros .
E agora eu tenho
ctbl()
:Observe que
ctbl()
, na verdade, não define as$[od][12...]
variáveis - nunca tem efeito duradouro em nenhum estado, mas$OPTARG
- apenas coloca a string$OPTARG
que pode ser usada para defini-las - e é assim que obtenho a segunda cópia de cada caractere acima, fazendo issoprintf "\\$o1\\$o2"
porque eles são definidos toda vez que eu avalio$(($OPTARG))
. Mas onde eu faço isso, também estou declarando um modificador de tamanho de campo paraprintf
o%s
formato de argumento de sequência de caracteres e, como a expressão sempre avalia o número total de bytes em um caractere, recebo o caractere inteiro na saída quando:fonte
[ "$(printf \\1)" ]|| ! echo but its not null!
enquanto isso , fique à vontade para se familiarizar melhor com a prática de comentários significativos, a menos que você recomende um concurso real ...?sh
linguagem de comando POSIX .bash
é um bourne novamente supra - definido do mesmo e, em grande parte, um motivador precipitado de grande parte dos cuidados prestados acima a tamanhos de caracteres honrosos amplamente portáteis, auto-expansíveis e com espaço para nome de qualquer tipo.bash
já deve lidar com muito disso, mas oc
idiomaprintf
estava, e talvez seja, deficiente na capacidade acima fornecida.Não é um script de shell, mas funciona
Saída de amostra
fonte
konsole
xxd<press enter>
<SHIFT+INSERT><CTRL+D>
você obtém algo como:
você sabe que o símbolo que você colou tem código hexadecimal
0xfb
fonte