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.