La sostituzione dei comandi può essere nidificata nella sostituzione delle variabili?


10

Vorrei usare la sostituzione variabile su una particolare stringa a cui accedo tramite un comando. Ad esempio, se copio qualcosa negli appunti, posso accedervi in ​​questo modo.

$ xclip -o -selection clipboard
Here's a string I just copied.

Se lo assegno a una variabile, allora posso fare la sostituzione della variabile su di essa.

$ 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.

Tuttavia, c'è un modo per fare la sostituzione delle variabili senza assegnarla a una variabile? Concettualmente, qualcosa del genere.

$ echo ${$(xclip -o -selection clipboard)/copi/knott}
bash: ${$(xclip -o -selection clipboard)/copi/knott}: bad substitution

Questa sintassi fallisce, perché vardovrebbe essere un nome variabile, non una stringa.

Risposte:


6

No, non puoi. bashe la maggior parte delle altre shell (tranne zsh) non consente la sostituzione nidificata.

Con zsh, puoi fare la sostituzione nidificata :

$ echo ${$(echo 123)/123/456}   
456

Accetterò questa risposta, poiché fornisce alcune prove circostanziali in cui non è possibile bash. (E mi spinge di nuovo verso la migrazione verso zsh.)
Sparhawk,

2

Sì, puoi farlo - in un certo senso. Non è proprio carino. È più come in linea che nidificato. Il problema è che devi operare sul valore del parametro che espandi - se quel parametro non ha valore, non farai molto. Quindi, puoi assegnare il valore mentre lo espandi ed è quasi una scorciatoia.

v=; echo "${v:=${0##*["$0${v:=$(xsel -bo)}"]}${v/copi/knott}}"

Uso l' $0espansione param all'interno della catena per nascondere il compito. Assegna il valore di var all'interno di un'espansione di assegnazione nidificata. L'esterno ha la precedenza - ma poiché si espanderebbe a qualunque cosa faccia l'interno è difficile da dire. Tuttavia, se silenziamo l'espansione interna, quindi la modifichiamo, puoi ottenere ciò che desideri. Dopo aver copiato la tua stringa negli appunti (non ho xclip- solo xsel) stampa:

Here's a string I just knotted.

È un po 'più chiaro cosa succede se si lascia $0fuori, però:

v=; echo "${v:=${v:=$(xsel -bo)}${v/copi/knott}}"

Che stampa:

Here's a string I just copied.  Here's a string I just knotted.

... poiché la cessione interna avviene prima della modifica, ma, come noto, l'assegnazione esterno ha la precedenza - e si espande a espansione sia di interno assegnazione la e alla modifica interna espansione.

Naturalmente nulla di tutto ciò funziona se il parametro target è già assegnato - quindi puoi farlo sicuramente solo se svuoti la variabile in primo luogo ... che, onestamente, è probabilmente il momento più conveniente per assegnarlo dopo tutto .


+1 per la soluzione alternativa, anche se come dici tu, è una soluzione che probabilmente è peggio che assegnare una variabile!
Sparhawk,

@Sparhawk - sì, decisamente peggio. E non c'è davvero niente di male in ogni caso - non c'è molto da guadagnare se non l'incertezza. Potresti trovare alcune aliasindicazioni indirette per renderlo un po 'più conveniente, ma se ne vale la pena, dovresti impostare una funzione per gestire preventivi sicuri e fare qualcosa con / evalo qualcosa del genere comunque. w / eval- se puoi fare in modo che i primi caratteri dell'output del comando sub corrispondano a una sintassi di espansione praticabile - allora probabilmente puoi ottenere molto più facilmente. So che una cosa del genere sarebbe facile con xsel- ci vuole stdin - ma xsel?
Mikeserv,

@Sparhawk - So solo come fare uno di questi, a proposito, perché in alcune situazioni può essere utile - come espansioni rapide o qui-doc - in cui non è possibile ottenere un compito di shell corrente da applicare in altro modo.
Mikeserv,

1

Se non si desidera creare una variabile, ci sono altri modi per eseguire la sostituzione di stringhe:

$ echo $(xclip -o -selection clipboard | sed 's/copi/knott/')
Here's a string I just knotted.

Grazie, sapevo che avrei potuto usare sedinvece, ma doveva essere più di una domanda generale, sulla nidificazione delle sostituzioni.
Sparhawk,

@Sparhawk Per quanto ne so, non si può fare una sostituzione variabile senza avere una variabile.
Giovanni 1024

Okay, questa è probabilmente la risposta allora. Lascerò la domanda aperta per alcuni giorni per vedere se qualcun altro ha una risposta referenziata, quindi accetterò questa altrimenti. Grazie.
Sparhawk,

@Sparhawk Molto bene.
Giovanni 1024

+1, ma accetterò un'altra risposta , poiché fornisce prove circostanziali leggermente più concrete che non funziona in bash.
Sparhawk,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.