Yalnızca n düzeyinde derin olan alt dizinleri listele


58

Festival, sesli posta verilerini aşağıdaki örnek dizin yapısında depolar:

/usr/share/festival/voices/<language>/<voicepack name>

Potansiyel olarak sayısız tüm alt dizinlerde lssadece <voicepack name>'ların çıktısını almak için en basit tek astar <language>hangisidir (tercihen kullanıyor ) ?

Yanıtlar:


80

Fedora'dayım ve bu sesli mesajlar biraz farklı bir konumda:

$ ls /usr/share/festival/lib/voices/*/ -1 | grep -vE "/usr|^$"
kal_diphone
ked_diphone
nitech_us_awb_arctic_hts
nitech_us_bdl_arctic_hts
nitech_us_clb_arctic_hts
nitech_us_jmk_arctic_hts
nitech_us_rms_arctic_hts
nitech_us_slt_arctic_hts

Bunu şu şekilde değiştirebilirsiniz:

$ ls /usr/share/festival/voices/*/ -1 | grep -vE "/usr|^$"

Find'ı kullanma

Kullanımı lsbu malikânede tipik çıkış nedeniyle hoş karşılanmaz lsayrıştırmak zordur. findKomutu kullanmak daha iyi , şöyle:

$ find /usr/share/festival/lib/voices -maxdepth 2 -mindepth 2 \
    -type d -exec basename {} \;
nitech_us_awb_arctic_hts
nitech_us_bdl_arctic_hts
nitech_us_slt_arctic_hts
nitech_us_jmk_arctic_hts
nitech_us_clb_arctic_hts
nitech_us_rms_arctic_hts
ked_diphone
kal_diphone

Find & basename detayları

Bu komut, bu dizine göre tam 2 kat derinlikte olan dosyaların tam yollarının bir listesini oluşturarak çalışır:

/usr/share/festival/lib/voices

Bu liste şöyle görünür:

$ find /usr/share/festival/lib/voices -maxdepth 2 -mindepth 2 
/usr/share/festival/lib/voices/us/nitech_us_awb_arctic_hts
/usr/share/festival/lib/voices/us/nitech_us_bdl_arctic_hts
/usr/share/festival/lib/voices/us/nitech_us_slt_arctic_hts
/usr/share/festival/lib/voices/us/nitech_us_jmk_arctic_hts
/usr/share/festival/lib/voices/us/nitech_us_clb_arctic_hts
/usr/share/festival/lib/voices/us/nitech_us_rms_arctic_hts
/usr/share/festival/lib/voices/english/ked_diphone
/usr/share/festival/lib/voices/english/kal_diphon

Ancak bu dizinlerin son bölümünü yaprak düğümü istiyoruz. Böylece onu basenameayrıştırmak için faydalanabiliriz :

$ basename /usr/share/festival/lib/voices/us/nitech_us_awb_arctic_hts
nitech_us_awb_arctic_hts

Hepsini bir araya getirerek, findher iki seviye derin dizinini komutun komuta geçirmesini sağlayabiliriz basename. Gösterim basename {}, bu temel ad dönüşümlerini yapan şeydir. -execAnahtarını kullanarak aramalar bulun .


lol, hemen hemen tam olarak aynı cevap, büyük beyinler ve bütün bu :).
terdon

+1 - Ne olduğunu anlarsa takılanlar için -exec basename {}, burada açıklayabilir misiniz?
user66001

@ user66001 - Bu yeterince açıklarsa bana bildirin.
slm

@ user66001 - sorununuzu tatmininize çözerse cevaplardan birini kabul edebilirsiniz 8-)
slm

1
Bul komutu, zamanın% 99'una ihtiyacım olan şey. Hem max hem de min sınır anahtarıydı - Ben sadece max yaptım. Örnek: find ~/ -maxdepth 1 -mindepth 1 -type d | xargs du -csh | sort -h
Boyuta göre

23

En kolay

ls -d /usr/share/festival/voices/*/*

Bu, kabuk tarafından tüm alt dizinlere /usr/share/festival/voices/ve daha sonra bu alt dizinlerin her birinin içeriğine genişletilir .

Sadece GNU’lar ve BSD’ler findgibi bazı uygulamalarla, başlığınızın önerdiği gibi belirli bir seviyeye inmek istiyorsanız :

find /usr/share/festival/voices/ -mindepth 2 -maxdepth 3 -type d

Bu, -type dalt dizindeki tüm dizinleri ( ) bulabilir /usr/share/festival/voices/, mindepth 2ancak 3 seviyeden daha düşük ( maxdepth 3) seviyesinden daha derin değildir . Kimden man find:

   -maxdepth levels
          Descend at most levels (a non-negative integer) levels of direc
          tories below the command line arguments.  -maxdepth 0
           means only apply the tests and  actions  to  the  command  line
          arguments.

   -mindepth levels
          Do  not apply any tests or actions at levels less than levels (a
          non-negative integer).  -mindepth  1  means  process  all  files
          except the command line arguments.

Evet aynaya bakmak gibi 8-)
slm

+1 İkinizin de nasıl 2 oy alması ilginç. Çapraz oylama her birini açıklar;) PS Dizin adlarını istedim, bu yüzden sadece bunu çözmek -type fzorunda kaldım -type d, değil mi? Ayrıca -exec basename {}
slm'nin

@ user66001 evet, -type ddizinleri bulacaktır. Bu basenameçok iyi bir fikir, sadece adını yazdıracak ve yolu kaldıracak. Sadece isimler istediğini varsayarsak, yapman gereken şey bu. man basenameVe ayrıca bir göz atın man dirname.
terdon

Teşekkürler terdon - Cevabınızı işaretlemediğim için üzgünüm. İhtiyacı olanlar için slm 'nin şu anki sürümünün daha fazla bilgiye sahip olduğunu hissettim .
user66001

1
@ user66001 her şeyden önce, kesinlikle haklısınız, slm gerçekten çok daha iyi. İkincisi, kabul etmediğiniz için asla özür dilememelisiniz, yalnızca bir tane olabilir ve bu en iyisini düşündüğünüz kişi olmalıdır :).
terdon

6

Kabul edilen cevap doğru çalışıyor ancak bir miktar verimsiz çünkü basenameher bir alt dizin için yeni bir süreç ortaya koyuyor :

find /usr/share/festival/lib/voices -maxdepth 2 -mindepth 2 \
    -type d -exec basename {} \;

Mümkün olduğunda find, yumurtlama işlemlerinin masraflarından kaçınmak için yerleşik özellikleri kullanmak tercih edilir . İşlemi findkullanarak basılı çıktısını değiştirme konusunda oldukça geniş bir kabiliyete sahiptir -printf. Varsayılan -print eylem tüm yolu yazdırır, ancak -printfve ve formatını kullanarak bir dizgeyi yazdırmak için yolun bölümlerini seçmek mümkündür. Yolun yalnızca dosya adı kısmını, öncü dizinler olmadan (aynen olduğu basename gibi) çıkarmak için , biçim dizesidir %f. Her dosya adından sonra yeni bir satır koymak için \naşağıdakileri ekleyin :

$ find /usr/share/festival/lib/voices -maxdepth 2 -mindepth 2 \
    -type d -printf '%f\n'
nitech_us_awb_arctic_hts
nitech_us_bdl_arctic_hts
nitech_us_slt_arctic_hts
nitech_us_jmk_arctic_hts
nitech_us_clb_arctic_hts
nitech_us_rms_arctic_hts
ked_diphone
kal_diphone

+1 Cevabınız için teşekkürler Michael. Ayrıca cevabınızda bunu yapmanın avantajını da görebiliyorum, ancak slm'in cevabına verilen işler göz önüne alındığında , kabul edilen cevabın değiştirilmesi konusunda iki fikrim var . @Slm bunu görürse ve bunu seçmekle ilgili bir sorunu yoksa, kabul edilen cevabı değiştirmek için buraya döneceğim.
user66001,

1
@ slm'in cevabı iyi açıklanmıştır ve findisteğe bağlı harici komutlarla kullanımın daha genel şeklini kapsar ; yerleşik işlemler için daha az etkilidir find. Cevabına yorum eklemeyi düşünmüştüm, ancak bu benden daha fazla itibar gerektiriyor. Şu anda kabul edilen cevabın doğru, iyi açıklanmış ve daha genel bir durum için bir kalıp olarak kullanılabildiğinden, kabul edilen cevabınızı değiştirmenize gerek yoktur; Sadece bu özel durum için daha etkili bir yöntem olduğunu belirtmek istedim.
Michael Henry,

0

TLDR; Bu sorunun başlığına göre buraya yeni gelenler için ; "Yalnızca n düzeyinde derin alt dizinleri listele" ye

find -maxdepth N

Nherhangi bir sayı nerede .

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.