Zsh'deki boşlukları içeren liste öğeleri


10

Bu noktada 2 saat boyunca zsh betikleri üzerinde çalışıyorum ve bir duvara çarptım. İçinde boşluk olabilecek dosyaların bir listesini gözden geçirmek istiyorum. Ben zsh oldukları sürece aşağıdaki örnekten tamamen farklı yaklaşımlara açığım çünkü zsh benim çalıştığım şeydir, senaryo yazmaya çalıştığım görev değil.

files=(`ls`)
for f in $files; do
    print $f
done

Açıkçası sadece yeniden yaratmak değil ls, sadece $fdöngü her yineleme tüm dosya adını yakalamak istiyorum .

Yanıtlar:


12

İlk olarak, kullanımının lssadece bir örnek olduğunu varsayıyorum . lsHerhangi bir kabuğun çıktısını ayrıştıramazsınız , çünkü belirsizdir. Bu sizin için haberse neden ls (1) 'in çıktısını ayrıştırmamanız gerektiğini okuyun . Herhangi bir kabukta, dosyaların bir listesini elde etmek için joker karakterler kullanın, örn files=(*).

Zsh'de, diğer kabuklarda olduğu gibi, komut ikamesinin sonucu , boşluk karakterlerinde kelimelere bölünür (daha doğrusu, değerine göre IFS). (Diğer mermilerin aksine, komut ikamesinin sonucu zsh cinsinden globbinge tabi değildir.) Yani lskomutun çıktısı

hello world
wibble

Daha sonra files=($(ls))ayarlar files3 elemanlarını içerdiği dizi: hello, worldve wibble.

Komut ikamesi çift tırnak içindeyse, bölme yapılmaz. Parametre genişletme bayrakları ile özel bölme yapabilirsiniz . @Bölme sonucunun bir dizi olacağını belirtmek için bayrağı kullanın (garip bir şekilde, çift tırnak içinde genişleme çift tırnak içinde tutmanız gerekir, yani "${(@)…}"çift ​​tırnaklı dize birden çok kelimeye genişleyecek olsa da). Bölmek için s, örneğin "${(@s:,:)…}"virgülle bölmek için bayrağı kullanın ; fbayrak sadece satırbaşıyla de böler.

files=("${(@f)$(ls)}")

Not genelde dizisi üzerinde yineleme uygun yol olduğunu for f in $files[@]gibi $filesboş elemanlar (elementler boş olmayacaktır çünkü burada, bu önemli değil) kapalı şeritler.

print $f$fa ile başlayıp -ters eğik çizgi genişliyorsa , bir anahtar olarak yorumlar $f. Kullanım print -r -- $fya print -rn -- $fsen dize sonra bir yeni satır eklemek istemiyorsanız.


Teşekkür ederim. Evet, sadece bir örnekti. Şu anda akılda belirli bir amaç yoktu, sadece liste öğelerini nasıl boşluk bırakacağını herhangi bir komuttan alıntılamayı veya kaçmayı bilmek istiyorum.
Felix

Kafa karıştırıcı bulduğum bir şey, dosyalarınızdaki dış () neden @f ile = ("$ {(@ f) $ (ls)}") ifadesinin gerekli olduğudur. Ve dışarıda () göründüğü sürece sadece (f) 'yi oynamak iyi çalışıyor.
Koobz

@Koobz 1. Dış (…), filesbir dize değil, bir dizidir (komutun satırlarının birleştirilmesini içerecek ve yapılan bölmeyi geri alacaktır (f)). 2. foo=$'one\n\nthree', contrast -rl $ {(f) foo} ` ile yazdırın ve print "${(@f)foo}". Çift tırnaklar, elde lsedemeyeceğiniz ancak diğer komutlarla gerçekleşebilecek boş satırları tutmak için gereklidir .
Gilles 'SO- kötü olmayı bırak

Çok takdir etmek. Bu deliliğin herhangi bir kafiye ya da nedeni var mı? Orada bile, kafa karıştırıcı olan şey, ara değer benim birleştirilmiş dizgiyse, dış () dizgiyi neden tek tek kelimeler üzerinde yeniden bölmüyor. Bu, örneğin yakut veya php'de dize enterpolasyonuna benziyor.
Koobz

@Koobz Boş kelimelerin özel muamelesinin nedeni, uzun zamandır unutulmuş eski zsh sürümleriyle tarihsel uyumluluktur. Otomatik olarak bölünmemesinin nedeni, şaşırtıcı ve çoğu zaman arzu edilmeyen bir davranış olmasıdır. Otomatik bölme, siz istemedikçe zsh'ın taklit etmediği Bourne kabuğunun bir davranışıdır.
Gilles 'SO- kötü olmayı bırak

2

Zsh'de, varsayılan olarak sözcük bölme gerçekleştirmeyen kabuğun genişlemesini kullanabilirsiniz. Deneyin

for f in /path/to/files/*; do
    print ${f}
done
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.