Na verdade, são quatro perguntas:
- Como conheço seus pontos de código?
- Algum tipo de regex?
- Como faço para contar quantas células de caracteres uma string leva?
- Como apago tudo o que foi enviado?
OP menciona o xterm, mas apenas os dois últimos são possivelmente específicos do xterm.
Para (1) e (2), o comando echo não ajuda muito. É melhor você usar printf
, que reconhece escapes de barra invertida. Em algumas implementações (por exemplo, GNU coreutils ), que inclui constantes Unicode, por exemplo,
printf '\u94f6\btest'
embora para expressões regulares , você está novamente melhor usando uma linguagem de script como o Perl (que pode manipular o UTF-8).
Leitura adicional:
- Como você faz uma eco a 4 caractere Unicode de dígitos no Bash?
- O comando printf
- O que é a melhor maneira de incorporar um caractere Unicode em um script de shell POSIX?
- Bash equivalente ao literal de string do Python para string utf conversão
As perguntas (3) e (4) são mais interessantes. Primeiro, o script não pode realmente informar quantas células de caracteres uma string recebe antecipadamente, mas pode apenas medi-las após o fato. Isso porque a largura é baseada em uma combinação de comportamento do terminal e do kernel.
- O xterm usa wcwidth para decidir a largura do personagem, com algumas questões sobre " fontes largas "(largura dupla) e implementações de wcwidth refletindo os vieses do desenvolvedor em relação aos valores Unicode de largura ambígua. O xterm pode ser configurado (em tempo de execução) para usar sua cópia da implementação de
wcwidth
; você é avisado de que pode não estar completo nem corresponder às informações reais do código de idioma do sistema. - quando o xterm é instruído a apagar parte de um caractere de largura dupla (como no exemplo dado), ele substitui a outra parte por um espaço. A maioria dos outros terminais que imitam o xterm faz isso (embora, em uma rápida verificação, eu notei um simplesmente movendo o cursor, fazendo com que o caractere largo e o texto ASCII se sobreponham). Se você sabia que o valor era de largura dupla, você poderia simplesmente ajustar sua noção de onde o cursor estava.
- o kernel do Linux não sabe nada sobre
wcwidth
. Sistemas baseados em Linux desde 2004 têm um recurso emstty
chamadoiutf8
:
which tells the kernel that input is encoded in UTF-8, for proper editing support in canonical input mode
- o recurso kernel do Linux é útil para editar entrada , porque ajuda o driver do terminal a fazer algo razoável quando um backspace exclui o caractere anterior. No entanto, não há recurso comparável para saída .
Você pode , como sugerido, usar o relatório de posição do cursor (uma sequência de escape) para encontrar a posição do cursor em pontos diferentes. Mas se você for usar isso para decidir como limpar a linha, pode parecer mais direto apenas mover para a posição antes de imprimir o valor Unicode e começar a limpar a partir desse ponto.
Como alternativa, você poderia dizer ao terminal para salvar a posição do cursor antes de imprimir o caractere largo e restaurá-lo (retroceder). Isso pode parecer mais limpo e mais previsível. Depois de restaurar a posição do cursor, você pode limpar a linha. Todos os três poderiam ser feitos usando sequências de escape - ou tput
:
tput sc
printf '\u94f6'
tput rc
tput el
printf 'test'
Além de uma demonstração, isso tem a desvantagem de que o terminal teria apenas uma posição salva para o cursor, e que, para garantir a limpeza de um caractere de largura única / dupla, está desmarcando uma linha inteira. Mas o cursor acabaria no lugar "certo".