Qual é o reverso do echo -e?

12

Se eu tiver uma string com caracteres não imprimíveis, novas linhas ou guias, existe uma maneira de usar echo para imprimir essa string e mostrar códigos para esses caracteres (por exemplo, \n para nova linha, \b de backspace)?

    
por drs 09.09.2014 / 03:22

6 respostas

6

Existem várias maneiras de fazer isso. Os dois mais portáteis que eu conheço são sed e od - ambos são POSIX.

printf '\n\r\b\t3[01;31m' | sed -n l

Ele gosta de ... read style escapes - estilo C.

OUTPUT

$
\r\b\t3[01;31m$

od é um pouco mais configurável ...

printf '\n\r\b\t3[01;31m' |
od -v -w12 -t c -t a -A n

 \n  \r  \b  \t 033   [   0   1   ;   3   1   m
 nl  cr  bs  ht esc   [   0   1   ;   3   1   m

Se você quer saber o que todas essas opções você pode procurar em man od , mas eu especificar que eu quero dois tipos de escapes - o -t c barra invertida escapa e os caracteres -t a nomeados. A opção -w usada acima não é especificada por POSIX.

E aqui está uma pequena função de shell que irá portar os valores octais de cada byte em seus argumentos - o que, é claro, od pode tratar também com -t o :

proctal() (LC_ALL=C
    for a do while [ -n "$a" ] 
    do printf %o\n "'$a"
    a=${a#?}; done; done)  

É simples. Isso é um pouco mais complicado. Ele deve ser capaz de fazer o que as implementações printf -q específicas do shell podem, no entanto.

bsq() (set -f; export LC_ALL=C IFS=\'
    for a do q=${a##*\'}; printf \'
    [ -n "${a#"$q"}" ] &&
        printf "%s'\''" ${a%\'*}
    printf "%s'\n'''''\n" "$q"; done |
    sed -n "/'''''"'/!H;1h;//!d;$!n;x;l' |
    sed -e :n -e '/\$/N;s/.\n//;tn
        s/\([^\]\\(\\\)*\)\([0-9]\)//g
        s/\\'"''/\\''"'/g;s/$$//'
)

Usando o exemplo de string anterior com um pouco mais de espaço:

bsq "$(printf '\n\r\'\''b\t3[01;31m')"

OUTPUT

'\n\r\'\''b\t
i=0
until [ $((i=$i+1)) -gt 5 ]
do touch "\%$i$(printf 'hey\b \t;\n3 ')"
done   #just for ugly's sake

bsq * | eval "
    printf '<%b>\n' $(tr \n \ )
" | tee /dev/fd/2 |
sed -n l
33[01;31m'

É apenas um pouco diferente. Você pode perceber que há um 0 extra e uma% extra de% ac_de% de ackslash. Isso permite uma tradução fácil para um argumento \b ou read %b . Por exemplo:

<\%1he  ;
>
<\%2he  ;
>
<\%3he  ;
>
<\%4he  ;
>
<\%5he  ;
>
<\%1hey\b \t;$
3 >$
<\%2hey\b \t;$
3 >$
<\%3hey\b \t;$
3 >$
<\%4hey\b \t;$
3 >$
<\%5hey\b \t;$
3 >$

OUTPUT

printf '\n\r\b\t3[01;31m' | sed -n l
    
por 09.09.2014 / 08:55
12

Quando você remove a opção -e para echo , em bash e desde que a opção xpg_echo não tenha sido ativada, ela deve imprimir as sequências como nada mais que seu texto original. Então \n e \t apareceriam literalmente como isso.

Exemplo

$ echo "hi\t\tbye\n\n"
hi\t\tbye\n\n

$ echo -e "hi\t\tbye\n\n"
hi      bye

Você também pode usar o comando interno printf de ksh93 , zsh ou bash para refiná-lo também.

$ printf "%q\n" "$(echo -e "hi\t\tbye\n\nbye")"
$'hi\t\tbye\n\nbye'

( bash output mostrado acima. Existem algumas variações dependendo do shell).

trecho de help printf em bash

%q quote the argument in a way that can be reused as shell input

    
por 09.09.2014 / 04:27
5

Você poderia usar algo como

$ cat filename
Ramesh is testing
New Line        is

Agora, você poderia fazer algo como

$ cat -A filename

Saída

Ramesh is testing$
New Line ^Iis $

Outro teste geral sem arquivos é o seguinte,

$ echo Hello$'\t'world. | cat -A

O comando acima gera a saída como

Hello^Iworld.$

Referências

por 09.09.2014 / 03:38
3

Com zsh , existem os sinalizadores de expansão de variável (q) , (qq) , (qqq) , (qqqq) que podem citar as variáveis de várias maneiras:

$ a=$'a b\nba\bc\u00e9
$ a=$'a b\nba\bc\u00e9%pre%'

$ printf '%s\n' $a
a b
bcé

$ printf %s $a | od -vtc
0000000   a       b  \n   b   a  \b   c 303 251  %pre%
0000013

$ printf '%s\n' ${(q)a}
a\ b$'\n'ba$'\b'cé$'%pre%'

$ printf '%s\n' ${(qq)a}
'a b
bcé'

$ printf '%s\n' ${(qqq)a}
"a b
bcé"

$ printf '%s\n' ${(qqqq)a}
$'a b\nba\bcé%pre%'

$ (){local LC_ALL=C; print -r -- ${(qqqq)a}}
$'a b\nba\bc31%pre%'
' $ printf '%s\n' $a a b bcé $ printf %s $a | od -vtc 0000000 a b \n b a \b c 303 251 %pre% 0000013 $ printf '%s\n' ${(q)a} a\ b$'\n'ba$'\b'cé$'%pre%' $ printf '%s\n' ${(qq)a} 'a b bcé' $ printf '%s\n' ${(qqq)a} "a b bcé" $ printf '%s\n' ${(qqqq)a} $'a b\nba\bcé%pre%' $ (){local LC_ALL=C; print -r -- ${(qqqq)a}} $'a b\nba\bc31%pre%'

No seu caso, você provavelmente desejaria um dos dois últimos.

    
por 09.09.2014 / 14:05
1

od -c imprimirá caracteres normais normalmente, mas caracteres especiais (guia, nova linha, etc.) e caracteres não imprimíveis como seu código de escape printf .

Então:

$ echo -e asdf\nghjk\003foo | od -c -An
   a   s   d   f  \n   g   h   j   k 003   f   o   o  \n

O -An informa od para não gerar o endereço.

    
por 09.09.2014 / 19:13
-1

Use o comando printf . Por exemplo:

printf "Hello\nthis is my line

irá produzir

Hello
this is my line
    
por 09.09.2014 / 06:29

Tags