O caractere ASCII do separador de unidades (ASCII 31, octal 37) é visível no Vim como a ^_
. Mas se eu imprimir o mesmo arquivo no terminal, o caractere será invisível. Isso faz com que os campos em uma linha fiquem presos juntos:
# In Vim and less:
first field^_second field^_last field
# cat the same file to terminal:
cat delim.txt
first fieldsecond fieldlast field
# print 2nd field with awk
cat delim.txt | awk 'BEGIN {FS = "\037"} {print $2}'
second field
Suponho que posso tornar o separador de unidades visível com cat -v:
cat -v delim.txt
first field^_second field^_last field
Mas isso é bastante complicado. Por que o separador de unidades não tem uma representação visível quando impresso em stdout no shell Bash? Não consigo nem copiar e colar a saída do shell corretamente; o separador de unidades se perde no processo.
Respostas:
O
US
caractere separador de unidade ( ), também conhecido comoIS1
, está nacntrl
classe de caracteres e não está naprint
classe de caracteres. É um caractere de controle destinado a organizar o texto em grupos, para programas projetados para usar essas informações . Em geral, os caracteres não imprimíveis provavelmente serão interpretados e renderizados de maneira diferente em diferentes programas ou ambientes.O motivo para vê-lo representado como
^_
no Vim é porque o Vim é um editor interativo. Ele pode renderizar livremente caracteres não imprimíveis como desejar, desde que o caractere binário correto seja gravado no disco.Você não pode obter o mesmo comportamento no shell porque os programas de shell Unix são escritos para operar e passar texto sem formatação um para o outro. Quando você
cat
cria um arquivo, o texto gravado no terminal deve ser o que realmente está no arquivo.Isso deixa para o dispositivo terminal interpretar o personagem. E verifica-se que alguns emuladores de terminais fazem tornar o
US
personagem de forma diferente dos outros. Nognome-terminal
(ou em qualquervte
terminal baseado em), o caractere será renderizado como uma caixa contendo o código hexadecimal001F
. Emxterm
ourxvt
, o personagem é realmente invisível.fonte
US
é totalmente invisível. Quando insiro esse caractere em um terminal comCtrl+/
(confirmado via<C-v><C-/>
), ele exclui uma quantidade imprevisível de texto na linha. Eu não entendo completamente seu comportamento, mas parece ter algum tipo de efeito de "guia inversa", onde, em vez de inserir vários espaços, exclui vários caracteres, mas às vezes insere texto aleatoriamente, por isso é confuso .O separador de unidades está no intervalo ASCII de caracteres de controle e, portanto, não possui (ou não costuma ter) uma representação visual.
O Vim e alguns outros editores os exibem, para que você possa editá-los. Como você notou, também
cat -v
exibe. A página de manual mostra, que-v
é a forma abreviada de--show-nonprinting
, que faz com que substitua os caracteres não imprimíveis por uma representação imprimível, que não é o conteúdo original do arquivo e, portanto, pode causar problemas, se a saída for realmente para outro programa .A representação que você vê já sugere que é um caractere de controle: um caractere anexado com a
^
é uma notação comum para Ctrl+ o caractere, que é a combinação de teclas que produz esse caractere em um terminal. Ctrl+ _permitirá inserir o separador de unidades no vim, por exemplo. Mas outro editor ou algum visualizador da GUI pode exibir o código hexadecimal, um espaço reservado ou algo completamente diferente.Como o seu terminal não imprime os caracteres de controle, ele também não é copiado ao selecionar o texto (os caracteres de espaço em branco como nova linha e guia são uma exceção aqui, que também são caracteres de controle). Outro exemplo de caracteres de controle no terminal que geralmente são ignorados ao copiar são os códigos de cores, que são um
ESC
caractere seguido pelo código para colorir o texto.Portanto, para mostrar os caracteres no seu terminal, não há outra maneira senão usar um programa que substitua o separador da unidade por algum caractere imprimível.
fonte
Um pouco na margem das outras respostas (muito boas), se você quiser alterar apenas o caractere de controle
^_
ao exibir o conteúdo do arquivo, poderá transliterá- lo usando otr
utilitário (e um pouco de sintaxe compatível com o bash) :Se você precisar substituir esse caractere de controle por seu formulário "expandido", precisará
sed
:Observe a sintaxe
$'\cX'
: essa sintaxe informa seu (shell compatível com bash) para substituir o caractere de controle correspondente. Consulte a Wikipedia para obter uma lista de alias de caracteres de controle usando a "notação de sinal de intercalação". Se você não gosta dessa sintaxe, pode preferir usar a notação octal$'\037'
ou hexadecimal$'\x1f'
.fonte