Estou tentando pesquisar e substituir uma variável usando a expansão do parâmetro $ {VAR // search / replace}. Eu tenho um PS1 bem longo e ruim, que eu quero descobrir o tamanho de depois da expansão. Para fazer isso, tenho que remover um monte de seqüências de escape que coloco nele. No entanto, ao tentar remover todas as seqüências ANSI CSI SGR, deparei-me com um problema com a minha sintaxe.
Dado o meu PS1 de:
PS1=\[\033]0;[\h] \w\007\]\[\033[1m\]\[\033[37m\](\[\033[m\]\[\033[35m\]\u@\[\033[m
\]\[\033[32m\]\h\[\033[1m\]\[\033[37m\]\[\033[1m\])\[\033[m\]-\[\033[1m\](\[\033[m
\]\t\[\033[37m\]\[\033[1m\])\[\033[m\]-\[\033[1m\](\[\033[m\]\[\033[36m\]\w\[\033[1m
\]\[\033[37m\])\[\033[35m\]${git_branch}\[\033[m\]\n$
(sim, está doente, eu sei ...)
Estou tentando fazer:
# readability
search='\\\[\\033\[[0-9]*m\\\]'
# do the magic
sane="${PS1//$search/}"
No entanto, estes parecem ser gananciosos no ponto de [0-9]
(quase como [0-9]
é tratado como um em .
vez disso):
echo "${PS1//$search/}"
\[\033]0;[\h] \w\007\]\n$
Se eu remover o *
e mudar [0-9]
para [0-9][0-9]
(como isso é mais ilustrativo), chego mais perto do resultado esperado:
$ search='\\\[\\033\[[0-9][0-9]m\\\]'
$ echo "${PS1//$search/}"
\[\033]0;[\h] \w\007\]\[\033[1m\](\[\033[m\]\u@\[\033[m\]\h\[\033[1m
\]\[\033[1m\])\[\033[m\]-\[\033[1m\](\[\033[m\]\t\[\033[1m\])\[\033[m\]-\[\033[1m
\](\[\033[m\]\w\[\033[1m\])$(git_branch)\[\033[m\]\n$
Por que o *
(zero ou mais) está fazendo coisas loucas? estou faltando alguma coisa aqui? Se eu passar o mesmo regex através do sed, obtenho o resultado esperado:
echo $PS1 | sed "s/$search//g"
\[\033]0;[\h] \w\007\](\u@\h)-(\t)-(\w)$(git_branch)\n$
fonte
extglob
afeta o comportamento de correspondência de padrões.*([0-9])
é o equivalente a[0-9]*
usarextglob
.Respostas:
Parece-me que você deseja remover as coisas entre
\[
e\]
:No entanto, a
bash
substituição é tão ineficiente que você provavelmente seria melhor dispararperl
oused
aqui, ou fazê-lo em um loop como:(essa é a sintaxe padrão do POSIX sh acima, BTW).
E se você quiser o prompt expandido a partir disso:
fonte
[
e]
. obrigado!Após algumas orientações do jordanm (e a leitura da seção "Correspondência de padrões" da página do manual do bash), verifica-se que esses padrões usados pela expansão de parâmetros não são regex. No entanto, no meu caso específico, se
shopt extglob
estiver ativado, eu posso fazer:onde
*([0-9])
é o mesmo que[0-9]*
em regex.Parece que o extglob fornece alguns mecanismos semelhantes ao regex com (da página de manual do bash):
fonte
extglob
implementa um subconjunto deksh
globs estendidos.ksh93
na verdade tem um operador de printf para converter entre padrões e REs (AT & T) (printf '%P\n' '\\\[[0-9]*\\\]'
dá*\\\[*([0-9])\\\]*
)Série completa de Pure Bash de sequências ANSI suportadas
fonte