Não é possível usar uma seqüência de escape em uma variável em um comando sed

1

Estou usando sed para destacar uma coluna na saída de um comando ps e ela funciona bem se eu codificar o código de cores. No entanto, a cor precisa ser dinâmica, então tentei movê-la para uma variável e fazer referência à variável no comando sed, mas parece que não funciona.

# Works
ps -eo pid,ppid,time,user,tty,%cpu,%mem,vsize,command --sort -%cpu | head  | sed -e $'s/ *[^ ]* /3[1;33m&3[0m/6'

Mas quando eu movo o 3[1;33m e o 3[0m para uma variável e faço referência a ele no comando (algumas maneiras diferentes), ele não funciona:

# None of the following work
fg_normal="3[0m"
fg_yellow="3[1;33m"

ps -eo pid,ppid,time,user,tty,%cpu,%mem,vsize,command --sort -%cpu | head  | sed -e $'s/ *[^ ]* /'$fg_yellow'&'$fg_normal'/6'
ps -eo pid,ppid,time,user,tty,%cpu,%mem,vsize,command --sort -%cpu | head  | sed -e $'s/ *[^ ]* /'"$fg_yellow"'&'"$fg_normal"'/6'
ps -eo pid,ppid,time,user,tty,%cpu,%mem,vsize,command --sort -%cpu | head  | sed -e $"s/ *[^ ]* /$fg_yellow&$fg_normal/6"

Alguma idéia?

    
por Justin 14.05.2016 / 00:02

3 respostas

2

Você pode usar:

fg_normal=$(echo -e "3[0m")
fg_yellow=$(echo -e "3[1;33m")

ou com tput:

fg_normal=$(tput sgr0)
fg_yellow=$(tput setaf 3)
    
por 14.05.2016 / 00:59
0

Você pode usar o printf ' %b specifier para montar o comando sed, preservando as seqüências de escape de barra invertida corretas:

ps -eo pid,ppid,time,user,tty,%cpu,%mem,vsize,command --sort -%cpu | head  | 
    sed -e "$(printf 's/ *[^ ]* /%b&%b/6' "$fg_yellow" "$fg_normal")"
    
por 14.05.2016 / 00:46
0

Você precisa entender que $'...' é um recurso do shell para gravar caracteres com escape. Um $'3' é um escape real ESC .

Portanto, você precisa mover o $' ' de dentro do comando sed:

sed -e $'s/ *[^ ]* /3[1;33m&3[0m/6'

Para as variáveis reais que você usará:

fg_normal=$'3[0m'
fg_yellow=$'3[1;33m'

Com essa simples mudança, isso (não é necessário usar $' agora) funcionará (observe as citações corretas dentro e fora das aspas simples '):

ps -eo pid,ppid,time,user,tty,%cpu,%mem,vsize,command --sort -%cpu |
head -n 10  |
sed -e 's/ *[^ ]* /'"$fg_yellow"'&'"$fg_normal"'/6'
    
por 14.05.2016 / 22:41