Não, você não pode. bash
e a maioria dos outros shells (exceto zsh
) não permitem substituição aninhada.
Com zsh
, você pode fazer substituição aninhada :
$ echo ${$(echo 123)/123/456}
456
Eu gostaria de usar a substituição de variáveis em uma string específica que eu acesse por meio de um comando. Por exemplo, se eu copiar algo na minha área de transferência, posso acessá-lo assim.
$ xclip -o -selection clipboard
Here's a string I just copied.
Se eu atribuí-lo a uma variável, então eu posso fazer uma substituição variável.
$ var=$(xclip -o -selection clipboard)
$ echo $var
Here's a string I just copied.
$ echo ${var/copi/knott}
Here's a string I just knotted.
No entanto, existe uma maneira de fazer a substituição de variáveis sem atribuí-lo a uma variável? Conceitualmente, algo assim.
$ echo ${$(xclip -o -selection clipboard)/copi/knott}
bash: ${$(xclip -o -selection clipboard)/copi/knott}: bad substitution
Esta sintaxe falha, porque var
deve ser um nome de variável, não uma string.
Não, você não pode. bash
e a maioria dos outros shells (exceto zsh
) não permitem substituição aninhada.
Com zsh
, você pode fazer substituição aninhada :
$ echo ${$(echo 123)/123/456}
456
Sim, você pode fazer isso - mais ou menos. Não é muito bonito. É mais como in-line do que aninhado. O problema é que você tem que operar no valor do parâmetro que você expande - se esse parâmetro não tiver valor, você não fará muito. Então, você pode atribuir o valor enquanto expandindo-o e dificilmente é um atalho.
v=; echo "${v:=${0##*["$0${v:=$(xsel -bo)}"]}${v/copi/knott}}"
Eu uso a expansão $0
param dentro da cadeia para ocultar a atribuição. Ele atribui o valor do var dentro de uma expansão de atribuição aninhada. O exterior tem precedência - mas porque se expandiria para qualquer coisa que seja interna, é difícil dizer. No entanto, se nós silenciarmos a expansão interna, então modificá-lo, você pode obter o que deseja. Depois de copiar sua string para minha área de transferência (não tenho xclip
- apenas xsel
) imprime:
Here's a string I just knotted.
É um pouco mais claro o que está acontecendo se você deixar $0
out, embora:
v=; echo "${v:=${v:=$(xsel -bo)}${v/copi/knott}}"
Isso imprime:
Here's a string I just copied. Here's a string I just knotted.
... porque a atribuição interna ocorre antes da modificação, mas, como notado, a atribuição externa tem precedência - e se expande para a expansão da atribuição interna e para a expansão interna modificada .
É claro que nada disso funciona se o parâmetro alvo já está atribuído - então você só pode fazê-lo com certeza se você esvaziar a variável ... o que, honestamente, é provavelmente o momento mais conveniente para atribuí-lo depois de tudo.
Se você não quiser criar uma variável, existem outras maneiras de realizar a substituição de strings:
$ echo $(xclip -o -selection clipboard | sed 's/copi/knott/')
Here's a string I just knotted.