Como inverter o cat -A?

1

Considere o seguinte:

$ cat -A input.txt
Hello^IWorld$
newline$

Aqui, cat -A usa novas linhas e guias reais, isto é, os caracteres reais, e os converte em representações.

Existe uma maneira de shell ou aplicação de linha de comando em repositórios do Ubuntu que permitiria tomar representações de caracteres não imprimíveis e gerar os valores real ?

De certa forma, estou perguntando se há algo análogo a $'Hello\tWorld\nnewline\n' , exceto que em vez de strings com aspas C, eu quero usar strings "com aspas na concha".

    
por Sergiy Kolodyazhnyy 25.01.2018 / 20:58

1 resposta

4

Bem, Python para o resgate!

Confira este one-liner, que lê de STDIN e imprime para STDOUT, lidando com todos os possíveis "caret escapes" / "códigos C0" (como ^I ) e indicadores de fim de linha ( $ ):

python3 -c 'import sys,re;print(re.sub(r"\^([A-Z?@[\\]^_])",lambda m:chr((ord(m.group(1))-64)&127),sys.stdin.read().replace("$\n","\n")))'

Na verdade, é compatível com python (2) e python3 . Aqui está uma versão mais longa e legível, fazendo basicamente o mesmo:

#!/usr/bin/env python3
import sys, re

# read everything from stdin and remove line-end indicators
s = sys.stdin.read().replace("$\n", "\n"))

# replace caret escapes like ^I or ^M and output to stdout
print(re.sub(r"\^([A-Z?@[\\]^_])", lambda m: chr((ord(m.group(1)) - 64) & 127), s)

Primeiramente, removemos os indicadores de fim de linha $ .

Segundo, usamos o padrão de expressão regular \^([A-Z?@[\\]^_]) para encontrar todos os caracteres válidos após o carets e substituir ambos pelo caractere sem escape correto, de acordo com a Wikipedia em Caret notation e Códigos de controle C0 . Observe como somente as letras maiúsculas A - Z ou uma de ?@[\]^_ têm um significado especial.

Agora, para desativar o código C0, tomamos a posição no alfabeto do caractere sucessivo do cursor (encontrado em m.group(1) ), por exemplo, "A" é 1, "B" é 2 e assim por diante. Isto é igual ao seu valor ASCII menos o código ASCII de "A" mais um, o que compõe o -64, o que também explica, e. "@" (ASCII 64) sendo 0 ou "[" (ASCII 91) sendo ESC (ASCII 27). Fazemos uma operação binária AND neste número com 127 para considerar apenas os primeiros 7 bits de informação, de modo que, e. "?" (ASCII 63 == 64-1) envolve 127, representando o caractere DEL.

Finalmente, após todos esses cálculos altamente complexos serem feitos, simplesmente imprimimos a string resultante novamente em STDOUT.

    
por Byte Commander 25.01.2018 / 21:50