Bash'te sadece ls kullanan dizinler mi listeleniyor?


954

Bu komut geçerli yoldaki dizinleri listeler: ls -d */

Desen tam olarak ne yapar */?

Ve ls -d /home/alice/Documentssadece bu yoldaki dizinleri listelemek için yukarıdaki komutta (örneğin ) mutlak yolu nasıl verebiliriz ?


7
Gerçekte ne anlama geldiğini açıklayan bu cevaptaki düzenlemeye bakın unix.stackexchange.com/a/75047/32647-d .
Evgeni Sergeev

Yanıtlar:


991

*/geçerli dizindeki tüm alt dizinlerle eşleşen bir modeldir ( *tüm dosya ve alt dizinlerle eşleşir ; /dizinlerle sınırlar). Benzer şekilde, / home / alice / Documents altındaki tüm alt dizinleri listelemek için şunu kullanın:ls -d /home/alice/Documents/*/


88
*/Gizli klasörlerle eşleşmeyeceğini unutmayın . Bunları dahil etmek için, bunları açıkça beğendiklerinizi belirtin ls -d .*/ */veya Bash'de seçeneği ayarlayındotglob .
Gergő

1
@ytpillai Bu, listelenecek alt dizin olmadığı için oluyor. Varolmayan bir lsşeyde her kullandığınızda bu hatayı alırsınız .
Gordon Davisson

1
Tamam, şimdi kontrol ettim ve tek dizinin kök klasör olduğu ortaya çıktı.
ytpillai

1
@GordonDavisson Bash seçeneği ile hata mesajı önlenebilirshopt -s nullglob

4
@BinaryZebra nullglob ayarı hata iletisini önler, ancak daha da karışıklığa neden olur: nullglob ayarlı ve alt dizinler olmadan , geçerli dizindeki tüm dosyaları listeleyecek şekilde ls */genişler ls. Bu durumda istediğin bu olmadığından eminim.
Gordon Davisson

481

Bunu yapmanın dört yolu, her biri farklı çıktı biçimine sahip

1. kullanma echo

Örnek: echo */, echo */*/
İşte ne var:

cs/ draft/ files/ hacks/ masters/ static/  
cs/code/ files/images/ static/images/ static/stylesheets/  

2. lsYalnızca kullanma

Örnek: ls -d */
İşte tam olarak ne var:

cs/     files/      masters/  
draft/  hacks/      static/  

Veya liste olarak (ayrıntılı bilgi ile): ls -dl */

3. lsve tuşlarını kullanarakgrep

Örnek: ls -l | grep "^d" İşte ne var:

drwxr-xr-x  24 h  staff     816 Jun  8 10:55 cs  
drwxr-xr-x   6 h  staff     204 Jun  8 10:55 draft  
drwxr-xr-x   9 h  staff     306 Jun  8 10:55 files  
drwxr-xr-x   2 h  staff      68 Jun  9 13:19 hacks  
drwxr-xr-x   6 h  staff     204 Jun  8 10:55 masters  
drwxr-xr-x   4 h  staff     136 Jun  8 10:55 static  

4. Bash Betiği (Boşluk içeren dosya adı için önerilmez)

Örnek: for i in $(ls -d */); do echo ${i%%/}; done
İşte ne var:

cs  
draft  
files  
hacks  
masters  
static

'/' Karakterini bitiş karakteri olarak kullanmak istiyorsanız, komut şöyle olacaktır: for i in $(ls -d */); do echo ${i}; done

cs/  
draft/  
files/  
hacks/  
masters/  
static/

2
NB. 3benim için diğerlerinden daha yavaştı. Test ettiğim dizinde: 1.012s, 2.016s, 3 .055s , 4.021s.
izomorfizmalar

@isomorphismes, zamanı nasıl ölçtün? Ne ile? Bu arada şunu söylemeliyim ki hayır 1benim favorim.
Albert

Albert, timeUnix işlevini kullandım. /// Katılıyorum, echo */daha akıllı ls -d */.
isomorphismes

9
Dikkat etmeniz gereken iki küçük şey. ls -l | grep "^ d" dizinlere sembolik bağlantıları filtrelerken, 'ls -d * /' bunları görüntüler. Ayrıca, hedef dizinde hiç dizin yoksa 'ls -d * /' başarısız olur.
Zoran Pavlovic

15
Bu 1.seçenek, boşluk içeren klasör adlarıyla uğraşırken büyük acılara neden olur.
Shrikant Sharat

99

Kullanırım:

ls -d */ | cut -f1 -d'/'

Bu, sonda eğik çizgisi olmayan tek bir sütun oluşturur - komut dosyalarında kullanışlıdır.

Benim görüşüm.


18
-1Seçeneği lsde olduğu gibi tek sütunlu bir formatta irade çıkışı ls -1 -d */.
Kalin

3
@ user29020 -1Yine de her giriş için bir eğik çizgi çıktığını unutmayın .
Dennis

Bunu .bashrctakma ad olarak eklediğimde nasıl eklerim '/'?
RNA

@RNA cevap vermek için geç, ama gelecekteki insanlar için: ters eğik çizgi ile kaçmayı deneyin? '\/'
Caek

1
Başında eğik çizgi varsa kırılır. Bu sadece sondaki eğik çizgileri kaldırır:| sed -e 's-/$--'
Victor Sergienko

62

Alt klasörleri olmayan tüm klasörler için :

find /home/alice/Documents -maxdepth 1 -type d

Alt klasörleri olan tüm klasörler için :

find /home/alice/Documents -type d

2
Soruyla eşleşmek için (ancak dotfiles ekleyin), ilk önce şöyle olmalıdır: find /home/alice/Documents -maxdepth 1 -mindepth 1 -type daksi takdirde /home/alice/Documentskendini dahil edersiniz . Dizinlere sembolik bağlantıları eklemek için-L
jhnc

Bulmak bu görev için yapılmış olan araç olduğundan, bu en sağlıklı çözümlere benziyor. Geçerli dizinin ilk sonucunu - ./ - grep -v '^ \ ./$'
siliconrockstar

38

4 (daha fazla) Güvenilir Seçenekler.

Bir işlem görmeyen yıldız *kabuk tarafından bir model (topak) olarak yorumlanır.
Kabuk bunu yol adı genişletmesinde kullanır.
Ardından, kalıba uyan dosya adlarının bir listesini oluşturur.
Basit bir yıldız işareti, PWD'deki (mevcut çalışma dizini) tüm dosya adlarıyla eşleşir. Sonundaki tüm dosya adlarıyla eşleşeceği
gibi daha karmaşık bir desen . Böylece, tüm dizinler. Bu yüzden komut:*//

1. yankı.

echo */
echo ./*/              ### avoid misinterpreting filenames like "-e dir"

(kabuk tarafından) echoPWD'deki tüm dizinlere genişletilecektir .


Bunu test etmek için: mkdirtest-dir gibi bir dizin ( ) oluşturun ve cdiçine:

mkdir test-dir; cd test-dir

Bazı dizinler oluşturun:

mkdir {cs,files,masters,draft,static}   # safe directories.
mkdir {*,-,--,-v\ var,-h,-n,dir\ with\ spaces}  # some a bit less secure.
touch -- 'file with spaces' '-a' '-l' 'filename'    # and some files:

Komut echo ./*/, tek adlandırılmış dosyalarla bile güvenilir kalır:

./--/ ./-/ ./*/ ./cs/ ./dir with spaces/ ./draft/ ./files/ ./-h/
./masters/ ./-n/ ./static/ ./-v var/

Ancak dosya adlarındaki boşluklar okumayı biraz kafa karıştırıcı yapar.


Bunun yerine, echokullanırız ls, kabuk hala dosya adları listesini genişleten şeydir. Kabuk, PWD'deki dizinlerin bir listesini almanın nedenidir. -dSeçeneği lsmarkaların yerine (varsayılan olarak sunulan gibi) her dizinin içeriğinin mevcut dizin girişinin sıralar.

ls -d */

Ancak, bu komut (bir şekilde) daha az güvenilirdir. Yukarıda listelenen tek adlandırılmış dosyalarla başarısız olur. Birkaç isim ile boğulur. Sorunlu olanları bulana kadar tek tek silmeniz gerekir.

2.- ls

GNU ls"seçeneklerin sonu" ( --) anahtarını kabul edecektir .

ls -d ./*/                     ### more reliable BSD ls
ls -d -- */                    ### more reliable GNU ls

3.-Printf

Her dizini kendi satırında listelemek için (ls -1'e benzer bir sütunda) şunu kullanın:

$ printf "%s\n" */        ### Correct even with "-", spaces or newlines.

Ve daha da iyisi, izini kaldırabiliriz /:

$ set -- */; printf "%s\n" "${@%/}"        ### Correct with spaces and newlines.

Böyle bir girişim:

$ for i in $(ls -d */); do echo ${i%%/}; done

Başarısız olacak:

  • ls -d */Yukarıda gösterildiği gibi bazı isimler ( ).
  • değerinden etkilenecektir IFS.
  • boşluklarda ve sekmelerdeki adları böler (varsayılan olarak IFS).
  • addaki her yeni satır yeni bir yankı komutu başlatır.

4.- Fonksiyon

Son olarak, bir fonksiyonun içindeki argüman listesinin kullanılması mevcut çalışan kabuğun argümanlar listesini etkilemez. basitçe:

$ listdirs(){ set -- */; printf "%s\n" "${@%/}"; }
$ listdirs

bu listeyi sunar:

--
-
*
cs
dir with spaces
draft
files
-h
masters
-n
static
-v var

Bu seçenekler, çeşitli garip dosya adlarıyla güvenlidir.


Güvenli kelimesini Güvenilir kelimesiyle değiştirmeniz gerektiğini düşünüyorum. Gönderiniz bana diğer çözümlerin 'güvensiz' (savunmasız veya sömürülebilir) olduğunu düşündürüyor
Amado Martinez

1
@AmadoMartinez Genel bir güvenlik / güvenilir / yapıldı. Daha iyi?

21

treeKomut burada da oldukça yararlıdır. Varsayılan olarak, bazı ascii karakterleri dizin ağacını gösteren tüm dosyaları ve dizinleri tam bir derinlikte gösterir.

$ tree
.
├── config.dat
├── data
   ├── data1.bin
   ├── data2.inf
   └── sql
|      └── data3.sql
├── images
   ├── background.jpg
   ├── icon.gif
   └── logo.jpg
├── program.exe
└── readme.txt

Ancak ascii ağacı olmadan ve geçerli dizinden tam yolla sadece dizinleri almak istersek şunları yapabilirsiniz:

$ tree -dfi
.
./data
./data/sql
./images

Argümanlar:

-d     List directories only.
-f     Prints the full path prefix for each file.
-i     Makes tree not print the indentation lines, useful when used in conjunction with the -f option.

Ve sonra mutlak yolu istiyorsanız, geçerli dizinin tam yolunu belirleyerek başlayabilirsiniz:

$ tree -dfi "$(pwd)"
/home/alice/Documents
/home/alice/Documents/data
/home/alice/Documents/data/sql
/home/alice/Documents/images

Alt dizin sayısını sınırlamak için, alt dizinlerin maksimum düzeyini aşağıdaki gibi ayarlayabilirsiniz -L level:

$ tree -dfi -L 1 "$(pwd)"
/home/alice/Documents
/home/alice/Documents/data
/home/alice/Documents/images

İnsan ağacı ile daha fazla tartışma görülebilir


15

Neden 'ls -d * /' çıktısının size aşağıdaki gibi iki eğik çizgi verdiğini merak ediyorsanız :

[prompt]$ ls -d */    
app//  cgi-bin//  lib//        pub//

Muhtemelen bir yerde kabuk veya oturum yapılandırma dosyaları -s bayrağı içeren ls sürümüne ls komutunun diğer adı. Bu bayrak her çıktı adına (bu düz bir dosya değil) ne tür bir şey olduğunu gösteren bir karakter ekler. Yani bir eğik çizgi '* /' deseniyle eşleşmektir ve diğer eğik çizgi ekteki tip göstergesidir.

Bu sorundan kurtulmak için, elbette ls için farklı bir takma ad tanımlayabilirsiniz. Ancak, takma adı geçici olarak çağırmamak için komutu ters eğik çizgi ile başlatabilirsiniz:

\ ls -d * /


11

Bunu sadece dosyama ekliyorum .bashrc(sadece bir oturum için ihtiyacınız varsa / istiyorsanız komut satırına da yazabilirsiniz)

alias lsd='ls -ld */'

lsd istenen sonucu verecektir.


Sadece kullanamaz mısın? ls -l yolu | grep dr
jrobertsz66

5
"o zaman lsd istenen sonucu verecektir." Ben gülmek
fbafelipe

1
Deneyimlerime göre, bir sonuç üretir.
Todd

'Lad' kullanıyorum (tüm dizinleri listeliyorum) ve ayrıca gizli dizinleri de dahil etmek için '. * /' Ekledim. Tabii ki, ima da bende kaybolmuyor.
DryLabRebel

11

lsDizinlere sembolik bağlantılar dahil gerçek çözüm

Buradaki birçok cevap , gerçek alt dizin eşleşmesi için joker karakter kullanırken gerçekte kullanmaz ls(veya yalnızca önemsiz anlamında kullanmaz) Sıralama düzeni için seçeneklerin kullanılmasına izin verdiği için ls -dgerçek bir lsçözüm yararlıdır ls.

Simgeler hariç

Bir çözüm kullanıldı ls, ancak diğer bağlantılardan farklı bir şey yapıyor, çünkü dizinlere sembolik bağlantıları dışlıyor :

ls -l | grep '^d'

(büyük olasılıkla dosya adlarından geçerek sedveya awkayırmak için)

Simgeler dahil

Dizinlere sembolik bağlantıların dahil edilmesi gereken (muhtemelen daha yaygın) durumda -p,ls (işaretli olanlar da dahil olmak üzere) dizin adlarına eğik çizgi karakteri eklemesini sağlayan :

ls -1p | grep '/$'

veya sondaki eğik çizgilerden kurtulmak için:

ls -1p | grep '/$' | sed 's/\/$//'

İçin seçenekler ekleyebiliriz lsGerektiği gibi (uzun bir liste kullanılıyorsa, -1artık gerekli değildir).

not: biz eğer istediğiniz eğik çizgileri, ama yapacak onları vurgulanan istemiyor grep, biz hackishly boşaltmak hattının fiili eşleşti kısmını yaparak vurgulama kaldırabilirsiniz:

ls -1p | grep -P '(?=/$)'

9

Gizli dizinin listelenmesi gerekmiyorsa, şunları öneririm:

ls -l | grep "^d" | awk -F" " '{print $9}'  

Ve gizli dizinlerin listelenmesi gerekiyorsa, şunu kullanın:

ls -Al | grep "^d" | awk -F" " '{print $9}'

VEYA

find -maxdepth 1 -type d | awk -F"./" '{print $2}'

Hakkında daha fazla bilgi edinmek awkistiyorsanız, lütfen bu cevaba bakın
PHP Öğrenen

Diğer cevaplara kıyasla ilk seçenek "ls .. | grep ... | awk" aşırı komut dosyası gibi görünüyor.
Lars Nordin

1
Hiçbir dizinin adlarında boşluk olmadığını varsayıyorsunuz.
Benjamin R

7

olmadan klasör listelerini göstermek /

ls -d */|sed 's|[/]||g'

2
veyals -d1 */ | tr -d "/"
ccpizza

Harici bir komut çağırmaya gerek yok:set -- */; printf "%s\n" "${@%/}"

@Wholanda çözümünü seviyorum. Biraz daha kısa çözümüm (test edildi ve çalışıyor): ls -d * / | sed 's | / || g'
klor

Ayrıca lsdir takma adı kullanmak da yararlıdır: takma ad lsdirs = "ls -d * / | sed 's | / || g'"
klor

6

İşte ne kullanıyorum

ls -d1 /Directory/Path/*;


Bu aslında satır satır görüntülemek için oldukça iyi bir çözümdür.
Nikolay Frick

Yalnızca dizinleri listelemez. Sondaki eğik çizgiyi eklemelisiniz:ls -d1 /Directory/Path/*/
Skippy le Grand Gourou

6

Yalnızca dizinleri listelemek için :

ls -l | grep ^d

yalnızca dosyaları listelemek için :

ls -l | grep -v ^d 

ya da şu şekilde yapabilirsiniz: ls -ld * /


4

Öğenin aşağıdakilere sahip bir dizin olup olmadığını test edin test -d:

for i in $(ls); do test -d $i && echo $i ; done

1
Lütfen bu kodun ne yaptığını ve soruyla nasıl ilişkili olduğunu açıklayın.
Ken YN

1
'ls' komutunu çalıştırır, sonra her biri bir
dizinse

3

*/ geçerli dizindeki dizinlerle eşleşen bir dosya adı eşleme desenidir.

Yalnızca dizinleri listelemek için bu işlevi beğendim:

# long list only directories
llod () { 
  ls -l --color=always "$@" | grep --color=never '^d'
}

Onu .bashrc'nize koyun.

Kullanım örnekleri:

llod       # long listing of all directories in current directory
llod -tr   # same but in chronological order oldest first
llod -d a* # limit to directories beginning with letter 'a'
llod -d .* # limit to hidden directories

NOT: -iseçeneği kullanırsanız kırılır . İşte bunun için bir düzeltme:

# long list only directories
llod () { 
  ls -l --color=always "$@" | egrep --color=never '^d|^[[:digit:]]+ d'
}

3

Bilginize, tüm dosyaları çok satırlı ls -1yazdırmak istiyorsanız, her dosyayı ayrı bir satıra yazdıracak bir dosya yapabilirsiniz. dosya1 dosya2 dosya3


3

Geçerli dizinin sade bir listesi:

ls -1d ./*/

Sıralanmasını ve temiz olmasını ister misiniz?

ls -1d ./*/ | cut -c 3- | rev | cut -c 2- | rev | sort

Unutmayın: büyük harfli karakterler sıralamada farklı davranışlara sahiptir


3

Bunu dene. Tüm linux dağıtımları için çalışır.

ls -ltr | grep drw

4
ls -l | grep '^d' | awk '{print $9}'
dw1

2

Sadece "buradan" dizinleri listelemek için bir astar.

Dosya sayısı ile.

for i in `ls -d */`; do g=`find ./$i -type f -print| wc -l`; echo "Directory $i contains $g files."; done

2

Kısmen ile çözdüm:

cd "/path/to/pricipal/folder"

for i in $(ls -d .*/); do sudo ln -s "$PWD"/${i%%/} /home/inukaze/${i%%/}; done

ln: «/home/inukaze/./.»: can't overwrite a directory
ln: «/home/inukaze/../..»: can't overwrite a directory
ln: accesing to «/home/inukaze/.config»: too much symbolics links levels
ln: accesing to «/home/inukaze/.disruptive»: too much symbolics links levels
ln: accesing to «/home/inukaze/innovations»: too much symbolics links levels
ln: accesing to «/home/inukaze/sarl»: too much symbolics links levels
ln: accesing to «/home/inukaze/.e_old»: too much symbolics links levels
ln: accesing to «/home/inukaze/.gnome2_private»: too much symbolics links levels
ln: accesing to «/home/inukaze/.gvfs»: too much symbolics links levels
ln: accesing to «/home/inukaze/.kde»: too much symbolics links levels
ln: accesing to «/home/inukaze/.local»: too much symbolics links levels
ln: accesing to «/home/inukaze/.xVideoServiceThief»: too much symbolics links levels

Bu bana, belediye başkanı kısma :)


2

Tam bir daire yapmak, her klasörün yolunu almak için ekleyerek, Albert'ın yanı sıra Gordans'ın yanı sıra oldukça yararlı olması gereken bir kombinasyonunu kullanın.

for i in $(ls -d /pathto/parent/folder/*/); do echo ${i%%/}; done

Çıktı:

/pathto/parent/folder/childfolder1/
/pathto/parent/folder/childfolder2/
/pathto/parent/folder/childfolder3/
/pathto/parent/folder/childfolder4/
/pathto/parent/folder/childfolder5/
/pathto/parent/folder/childfolder6/
/pathto/parent/folder/childfolder7/
/pathto/parent/folder/childfolder8/


1

İşte sadece dizin adlarını listelemek için kullandığım şey:

ls -1d /some/folder/*/ | awk -F "/" "{print \$(NF-1)}"

1

Orijinal soruyu cevaplamak, kendi başına bir */ilgisi yoktur ls; globbing olarak bilinen bir süreçte kabuk / Bash tarafından yapılır. .

Bu nedenle echo */ve ls -d */çıkış aynı unsurları. ( -dBayrak, lsçıktıyı dizinlerin içeriğini değil dizin adlarını yapar .)


1

Burada dizin adlarını yalnızca ayrı satırlarda çıkaran bir ağaç varyasyonu var, evet çirkin ama hey, işe yarıyor.

tree -d | grep -E '^[├|└]' | cut -d ' ' -f2

veya awk ile

tree -d | grep -E '^[├|└]' | awk '{print $2}'

Ancak bu muhtemelen daha iyidir ve /sonraki dizin adını korur .

ls -l | grep "^d" | awk '{print $9}'

Bu Korece benziyor!
Paschalis

0
file *|grep directory

O / P (Makinemde) -

[root@rhel6 ~]# file *|grep directory
mongo-example-master:    directory
nostarch:                directory
scriptzz:                directory
splunk:                  directory
testdir:                 directory

Yukarıdaki çıktı kesim kullanılarak daha da geliştirilebilir.

file *|grep directory|cut -d':' -f1
mongo-example-master
nostarch
scriptzz
splunk
testdir

* could be replaced with any path that's permitted
 file - determine file type
 grep - searches for string named directory
 -d - to specify a field delimiter
 -f1 - denotes field 1

0

Sadece dizinleri listelemek için şimdiye kadarki en kısa komut (aslında bir hack). İlgilenilen dizinin mutlak yolunu veya göreceli yolunu yazın ve ilgilenilen dizini girmek için enter tuşuna basın. Şimdi sekme tuşunu yazın cdve basın . Yalnızca dizinler gösterilir.

user@ubuntu:~/Desktop$cd <tab key>

Yukarıdaki komut artık yalnızca Masaüstü'ndeki klasörleri görüntülemelidir . Gerçekten en kısa.


Bu, otomatik tamamlamanın etkin olduğunu ve her durumda çalışmayabileceğini varsayar. Ayrıca, çıktıyı bir şeye dönüştürmek gibi bir şey yapmak istiyorsanız, işe yaramaz. Ancak çıktıyı görmek için hızlı ve kolay çalıştığından emin olun.
lacostenycoder

Mükemmel! "." Ve sonra çalıştı
user2060451
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.