Komut ikamesi, değişken ikamede yuvalanabilir mi?


10

Bir komut aracılığıyla eriştiğim belirli bir dize değişken ikame kullanmak istiyorum. Örneğin, panomuza bir şey kopyalarsam, buna böyle erişebilirim.

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

Eğer bir değişkene atarsam, değişken üzerinde değişiklik yapabilirim.

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

Ancak, bir değişkene atamadan değişken ikamesi yapmanın bir yolu var mı? Kavramsal olarak, böyle bir şey.

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

Bu sözdizimi başarısız olur, çünkü vardize değil değişken bir ad olmalıdır.

Yanıtlar:


6

Hayır, yapamazsınız. bashve diğer mermilerin çoğu (hariç zsh) yuvalanmış değiştirmeye izin vermez.

İle zsh, iç içe geçmiş değiştirme yapabilirsiniz :

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

Bu cevabı kabul edeceğim çünkü mümkün olmadığına dair bazı kanıtlar sağlıyor bash. (Ve beni tekrar göç etmeye doğru itiyor zsh.)
Sparhawk

2

Evet, bunu yapabilirsiniz - bir çeşit. Gerçekten hoş değil. İç içe olmaktan çok satır içi gibi . Sorun, genişlettiğiniz parametrenin değeri üzerinde çalışmanız gerektiğidir - bu parametrenin değeri yoksa, fazla bir şey yapmazsınız. Yani, değeri atayabilirsiniz ederken bunu genişleterek ve pek bir kestirme.

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

Görevi gizlemek için $0zincirdeki param genişlemesini kullanıyorum . İç içe geçmiş atama genişletmesi içinde var'ın değerini atar. Dış öncelik taşır - ama içsel olana ne olursa olsun genişleyeceği için söylemek zor. Ancak, iç genişlemeyi susturursak, onu değiştirirsek, istediğiniz şeyi elde edebilirsiniz. Dize benim panoya kopyaladıktan sonra (ben - sadece ) yazdırır:xclipxsel

Here's a string I just knotted.

Yine de $0, dışarıda kalırsanız neler olduğu biraz daha açıktır :

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

Bu yazdırır:

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

... çünkü içsel atama değişiklikten önce gerçekleşir, ancak belirtildiği gibi, dışsal atama öncelik taşır - ve hem iç-atamanın genişlemesine hem de değiştirilmiş iç-genişlemeye genişler.

Tabii ki, hedeflenen parametre zaten atanmışsa bunların hiçbiri işe yaramıyor - bu nedenle, değişkeni yalnızca ilk etapta boşaltırsanız yapabilirsiniz ... dürüst olmak gerekirse, muhtemelen sonuçta atamak için en uygun zamandır. .


Geçici çözüm için +1, ancak söylediğiniz gibi, büyük olasılıkla bir değişken atamaktan daha kötü bir geçici çözümdür!
Sparhawk

@Sparhawk - evet, kesinlikle daha kötü. Yine de yanlış olan hiçbir şey yok - belirsizlik dışında kazanılacak çok şey yok. aliasBiraz daha uygun hale getirmek için bazı dolaylı işlemler yapabilirsiniz - ancak size değerse, güvenli alıntı yapmak ve evalyine de w / veya bunun gibi bir şey yapmak için bir işlev kurmalısınız . w / eval- komut alt çıktısının ilk karakterlerini uygulanabilir genişletme sözdizimine dönüştürürseniz - muhtemelen daha da kolaylaştırabilirsiniz. Böyle bir şey kolay olacağını biliyorum w xsel- - stdin alır - ama xsel?
Mayıs 15'te mikeserv

@Sparhawk - Sadece bu arada nasıl yapacağımı biliyorum, çünkü bazı durumlarda, aksi takdirde uygulamak için geçerli bir kabuk ataması alamayacağınız hızlı veya burada belge genişletmeleri gibi yararlı olabilir.
mikeserv

1

Bir değişken oluşturmak istemiyorsanız, dize değiştirme işlemini gerçekleştirmenin başka yolları da vardır:

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

Teşekkürler, sedbunun yerine kullanabileceğimi biliyordum , ancak ikamelerin yuvalanması konusunda daha genel bir soru olması gerekiyordu.
Sparhawk

@Sparhawk Bildiğim kadarıyla, bir değişken olmadan değişken değiştirme yapılamaz.
John1024

Tamam, muhtemelen cevap budur. Başka birinin referanslı bir cevabı olup olmadığını görmek için soruyu birkaç gün açık bırakacağım, daha sonra bunu kabul edin. Teşekkürler.
Sparhawk

@Sparhawk Çok iyi.
John1024

+1, ancak başka bir cevabı kabul edeceğim , çünkü bash'da işe yaramadığına dair biraz daha somut koşullu kanıt sağlıyor.
Sparhawk
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.