Eşleşen dizinden bir düzey derinlikteki dizinlerin listesini bulun


13

Belirli bir klasörde bulunan dizinlerin listesini almaya çalışıyorum.

Bu örnek klasörler göz önüne alındığında:

foo/bar/test
foo/bar/test/css
foo/bar/wp-content/plugins/XYZ
foo/bar/wp-content/plugins/XYZ/js
foo/bar/wp-content/plugins/XYZ/css
baz/wp-content/plugins/ABC
baz/wp-content/plugins/ABC/inc
baz/wp-content/plugins/ABC/inc/lib
baz/wp-content/plugins/DEF
bat/bar/foo/blog/wp-content/plugins/GHI

Geri dönecek bir komut istiyorum:

XYZ
ABC
DEF
GHI

Aslında, wp-content / plugins / içindeki klasörleri arıyorum

Kullanmak findbeni en yakına getirdi, ancak kullanamıyorum -maxdepth, çünkü klasör aradığım yerden değişken bir şekilde uzakta.

Aşağıdakileri çalıştırmak tüm alt dizinleri yinelemeli olarak döndürür.

find -type d -path *wp-content/plugins/*

foo/bar/wp-content/plugins/XYZ
foo/bar/wp-content/plugins/XYZ/js
foo/bar/wp-content/plugins/XYZ/css
baz/wp-content/plugins/ABC
baz/wp-content/plugins/ABC/inc
baz/wp-content/plugins/ABC/inc/lib
baz/wp-content/plugins/DEF
bat/bar/foo/blog/wp-content/plugins/GHI

Yanıtlar:


14

-pruneBulunan dizinlerin içine düşmemesi için bir ekleyin.

find . -type d -path '*/wp-content/plugins/*' -prune -print

*wp-content/plugins/*Ayrıca bir kabuk glob olduğu için alıntı yapmalısınız.

GNU için, bunların tam yolunu değil, yalnızca dizin adlarını istiyorsanız find, size yerini alabilir -printile -printf '%f\n'veya boru, dosya yolları yeni satır karakterleri içermeyen yukarıdaki komutun çıktısını varsayarak awk -F / '{print $NF}'ya sed 's|.*/||'da dosya yolları içeriyor varsayarak ( yalnızca geçerli karakterler).

İle zsh:

printf '%s\n' **/wp-content/plugins/*(D/:t)

**/altdizinlerinden biri seviyesidir (özellik kaynak zsherken nighties içinde ve şimdi seviyorum diğer birçok kabuklarında bulunan ksh93, tcsh, fish, bash, yashgerçi genelde bazı seçeneği altında), (/)tip sadece dosyaları seçmek için dizine , Dgizli (nokta) olanları içerecek şekilde, :thiç olsun kuyruk (dosya adı).


Bu bulgu dirs'deki yeni satırları a ?. Bash için (soruda etiketlendiği gibi) bu işe yarar .
Isaac

@sorontar, yazdırılamayan karakterler için findbir ?ya da herhangi bir değiştirme karakteri ya da herhangi bir kaçış biçimi çıkaran uygulamalar, çıktıyı bir terminale gittiğinde yapar, burada olduğu gibi bir boruya giderken değil.
Stéphane Chazelas

Cevabınızdaki ilk (ve yalnızca zsh olmayan) komutun hiç borusu yok, test ettiğim ve yeni satırları değiştiren komut. Söylediğiniz gibi, "dosya yollarının yeni satır karakterleri içermediği varsayılarak" ifadesi verildiğinde, yeni satırlarda da başarısız olduğunu zaten itiraf ettiniz.
Isaac

@sorontar üzgünüm yeni satırlar biz yapıyoruz varsayım kırmaz yüzden kaçtı olacağını gibi OK çalışacak söyleyen ikinci kısmı üzerinde yorum sanıyordum sed/ ' awktüm dosyaları bir çizgi üzerinde olduğunu. Şimdi, Bir ABC?BCDveya ABC\nBCDetkileşimli / terminal çıkışı için iki ABCveya BCDbir çağrı için bir satır almak daha yararlı olacağını iddia edilebilir $'ABC\nBCD. Bu, kullanıcı sunumu seviyesinde $'AB\bC', çıktı bir terminale gittiğinde, ACböyle bir ?yedek olmadan göreceğiniz bir dosya için ...
Stéphane Chazelas

-Prune ile bulun ve çıktı biçimini değiştirmek için printf kullanmak tam olarak istediğim şeyi verdi. Mükemmel teşekkürler!
Nick

4

Bash-ically:

shopt -s globstar
printf "%s\n" **/wp-content/plugins/*

baskılar:

bat/bar/foo/blog/wp-content/plugins/GHI
baz/wp-content/plugins/ABC
baz/wp-content/plugins/DEF
foo/bar/wp-content/plugins/XYZ

veya

shopt -s globstar
for d in **/wp-content/plugins/*; do printf "%s\n" ${d##*/}; done

baskılar:

GHI
ABC
DEF
XYZ

Hayır, dosyaları direkler içinde de basacaktır. Lütfen cevabımı okuyun.
Isaac

İyi bir nokta; teşekkür ederim! Dizin yapısını yeniden oluşturmuştum, ancak test dosyalarını yerleştirmedim.
Jeff Schaller

4

Sen olabilir findçeşit, recurse:

find / -type d -path *wp-content/plugins -exec find {} -maxdepth 1 -mindepth 1 -type d \;

3

Bash için: Basit ( boşluklu ve yeni satırlı dosyalar / dizinler için çalışır ):

shopt -s globstar                    # allow ** for several dirs.
a=(**/wp-content/plugins/*/)         # capture only wanted dirs.
a=("${a[@]%/}")                      # remove trailing slash (dirs) `/`.
printf '%s\n' "${a[@]##*/}"          # print only the last dir name.

Wll baskı:

GHI
ABC
DEF
XYZ

Oluşturulan dosyalar olsa bile.


Gizli dizinlere bakmadığını, gizli dosyaları atladığını ( dotglobistenmeyen seçeneklere bakın ) ve dizinlere ek olarak dizinlere sembolik bağlantıları da içerdiğini unutmayın ( **ayrıca 4.2 ve önceki sürümlerde sembolik bağlantıları da geçecektir).
Stéphane Chazelas

@ StéphaneChazelas gizli dosyalar? Soru hiçbirini istemez, sadece dirs. Evet, gizli dizinler bağımsız olarak seçilebilir (istenirse bir özellik olarak). Ve evet, semboller bash'ın geçerli sürümünde enine değil.
Isaac

1
lütfen yorumlarımı saldırganlık olarak görmeyin. Cevabınızı onayladım ve bununla ilgili açık olmayan bazı gerçekleri belirtmek için altına bir not ekledim. findhiçbir dosyayı hariç tutmaz. globs nokta dosyalarını hariç tutar, ikisi arasında bir fark olarak işaret etmeye değer.
Stéphane Chazelas

3

treeKomut bu amaç için tam olarak tasarlanmıştır. Derinlik -Lbayrak ile kontrol edilebilir . İşte sürdürdüğüm yerel bir Wordpress sitesinde bir örnek:

$ tree -L 1 wp-content/
wp-content/
├── index.php
├── plugins
└── themes

2 directories, 1 file

$ tree -L 2 wp-content/
wp-content/
├── index.php
├── plugins
   ├── akismet
   ├── contact-form-7
   ├── index.php
   └── wordpress-seo
└── themes
    ├── index.php
    ├── twentyfifteen
    └── twentysixteen

11 directories, 3 files

$ tree -L 1 wp-content/plugins/
wp-content/plugins/
├── akismet
├── contact-form-7
├── index.php
└── wordpress-seo

5 directories, 1 file

1

DopeGhoti'nin cevabına dayanarak, eşleşme döngüsü hakkında:

find / -type d -iregex '.*/wp-content/plugins' -print0 | while read -r -d $'\0' D; do
    find "$D" -maxdepth 2 -mindepth 1
done

Bunu yapmanın nedeni, -exec\ n '' vb.


0

Başladığınız şeylere dayanarak:

find -type d -path *wp-content/plugins/* | egrep -o "wp-content/plugins/[^/]+($|/)" | sed -r "s~wp-content/plugins/([^/]+)($|/)~\1~" | uniq  

egrep, * wp-content / plugins / * ve bir sonraki eğik çizgiye / veya satır sonuna kadar olan karakterleri - istediğiniz bölümü içerir.

sed , ~ sınırlayıcı ile ilk parantez () kümesini kullanarak istediğiniz bölümü seçer ve her şeyin yerine \ 1 (istediğinizi) kullanır

uniq yinelenen sonuçları filtreler

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.