Özyineli glob?


80

Böyle bir şey yazmak istiyorum:

$ ls **.py

Tüm .py dosya adlarını elde etmek için, bir dizini hiyerarşisini tekrarlayarak yürüyün.

Bulunacak .py dosyaları olsa bile, kabuk (bash) bu çıktıyı verir:

ls: cannot access **.py: No such file or directory

İstediğimi yapmanın bir yolu var mı?

EDIT: Belirli bir durumla ilgilenmediğimi belirtmek isterim ls, ancak soru glob sözdizimi ile ilgilidir.

Yanıtlar:


98

Özyinelemeli globları bash yapmak için globstar, bash 4 veya daha üst sürümdeki özelliğe ihtiyacınız var .

Bash manpage'den:

globstar
    If set, the pattern ** used in a pathname expansion context will
    match all files and zero or more directories and subdirectories.
    If the pattern is followed by a /, only directories and
    subdirectories match.

Örnek modeliniz için:

shopt -s globstar
ls **/*.py

2
Ben de etkinleştirilmesini tavsiye ederimnullglob
glenn jackman 4:12

6
@glennjackman Ancak nullglob, etkinleştirmeden önce , aşağıdaki uyarıları okumayı şiddetle tavsiye ederim .
Serge Stroobandt

2
^ Uyarılar buraya taşındı .
usandfriends

1
Bash 3.2 ile wc -l {**,.}/*.pygayet iyi çalışıyor
Raphael,

@Raphael Sürüm notlarını iki kez kontrol ettim ve kesinlikle 4.0'da tanıtıldığını söylüyor. Belki de dağıtım bunun için bir yamayı desteklemiştir? IIRC RHEL 5 bazı özellikleri destekledi. Ayrıca, bash 4'ün yayınlanmasından bu yana 9 yıl geçti ...
jordanm

10
find . -name '*.py'

** her ikisi de geçerli dizinde çalışan, tek bir şeyden daha fazlasını * yapmaz


İlginç. Yine de, daha çok glob sentaksına odaklandım çünkü bir konfigürasyon dosyasında kullanmak zorundayım (direktif dahil). Bir dosya listesine ihtiyacım yok.
Paolo

2
@Doug O'Neal, bu artık doğru değil. bash, şu zsh özelliğini kopyaladı (
ksh93'ün ksh93'ünkine

Eğer yapabileceğiniz pek çok şey vardır findsen bash 4. Örnekler yoksa: yourcommand `find . -name '*.py'`(komutu ters tırnak dikkat edin); find . -name '*.py' -exec yourcommand {} \;.
Mars

5

Bash 4'ten (zsh da dahil) yeni bir globbing seçeneği ( globstar) eklendiğinde, deseni **farklı şekilde ele alan bir seçenek eklendi .

Joker desenle eşleşiyor ve komuttaki joker desenle eşleşen öğelerle değiştirilerek eşleşen dosya ve dizin adlarını döndürüyor.

Normalde, kullandığınızda **, benzer şekilde çalışır *, ancak yinelenerek tüm dizinleri yinelenir (bir döngü gibi).

Etkin olup olmadığını görmek için kontrol edin shopt globstar(komut dosyasında, kullanın shopt -q globstar).

Örnek **.pysadece geçerli dizin için işe yarar, çünkü recurses olabilecek dizinlerin listesini döndürmez, bu yüzden birden fazla dizin düzeyinde joker karakter kullanmanız gerekir **/*.py, böylece daha derinlere inebilir.

Lütfen tüm dosyaları tekrarlı olarak bulmak için yaptığım birkaç sözdizimi testini bulun .

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.