Bash: ls * klasör gruplaması olmadan


12

Ben yazarsam:

ls source/*

source/fonts:
fontello

source/images:
bg1.png                eng.png        fra.png   

Klasör adlarına göre gruplandırılmış dosyaların listesini alıyorum. Dosya adlarının listesini nasıl alabilirim?

ls source/*

source/fonts/fontello
source/images/bg1.png
source/images/eng.png
source/images/fra.png   

Teşekkürler


Bu komut dosyası kullanımı içinse, mywiki.wooledge.org/ParsingLs adresini görmek isteyebilirsiniz . (Yani, findyanlış kullanmanın da yolları var ; özellikle koşuyorsanız for file in $(find ...), bunlardan birine çarptısınız).
Charles Duffy

Yanıtlar:


13

Çıktı değişikliği olmadan mümkün görünmüyor, ancak burada kolay bir alternatif yol var:

find source/ -type f

Veya (yalnızca GNU find'a özel), dosyaları yalnızca sorunuzun derinliklerine getirmek için:

find source/ -type f -mindepth 2 -maxdepth 2

(veya size lsverdiği gibi dizinleri istiyorsanız, kaldırın -type f)


5

Bazı psychedlics ( ls -d) eklerseniz ls'e yapıştırabilirsiniz :

# mkdir test
# cd test
# mkdir A B C
# touch {A,B,C}/file*
# ls -d */*    
A/file  B/file  C/file

@Cthulhu tamam örneğim çok kısa, A, B a / o C klasörleriniz varsa -d yalnızca seçtiğiniz öğeyi görüntülemeye yardımcı olur. Aslında bulmayı sevmiyorum ve derinliği ls -d ile tartışarak tanımlayabilirsiniz
ikrabbe

Derinliği sınırlamak için diğer cevaba bir düzenleme önerdim.
o11c

@ o11c çok iyi, ama yine findde şişman bir canavar.
ikrabbe

3

“Zavallı adamın” ilgini çekebilir find:

shopt -s globstar

shopt -s s adında kabuk seçeneği (ler) ETS. globstarŞöyle tanimlanirsa Bash (1) :

**Ayarlanırsa, dosya adı / yol adı genişletme bağlamında kullanılan desen bir dosya [sic] ile sıfır veya daha fazla dizin ve alt dizinle eşleşir . Desenin ardından a gelirse /, yalnızca dizinler ve alt dizinler eşleşir.

Yani, yaptıktan sonra shopt -s globstar, aşağıdaki komutlardan herhangi biri:

ls -d1 - kaynak / **                  # 'd'den sonraki karakter bir rakamdır. 
ls -d - kaynak / ** | cat             # yani, herhangi bir komuta boruya yazacaktır. 
printf "% s \ n" kaynak / **

çıktı üretecek:

source/
source/fonts
source/fonts/fontello
source/images
source/images/bg1.png
source/images/eng.png
source/images/fra.png

Ne yazık ki, dizin adları da buna dahildir. Size yardımcı olabilecek bir az şey olduğunu bilmek

printf "%s\n" source/**/

çıktı üretecek:

source/
source/fonts
source/images

yani, sadece dizin adları. Sen, bir dosyaya komutları ilk seti birinin çıkışını yönlendirmek ikinci dosyaya yukarıdaki çıktısını yönlendirmek ve ardından kullanabilir comm, diffveya benzer bir şey, sadece sade bırakarak birinci gelen ikinci dosyayı çıkarmak dosyaları (dizin olmayanlar). Ama yapma.

Başka bir yaklaşım (bu daha iyi değil )

ls -d --file-type -- source/** | grep -v '/$'

Bu --file-typeseçenek, her dizin adının sonunda (ve diğer (özel) dosya türlerinin uçlarındaki diğer karakterler) şu lsşekilde görüntülenmesini söyler /:

source //                             # Fazladan bir 
kaynak eklendi kaynak / yazı tipi /                        # Bir tane eklendi
Kaynak / yazı / fontello
kaynak / resim /                       # Bir tane eklendi
kaynak / images / bg1.png
kaynak / images / eng.png
kaynak / images / fra.png

ve sonra grep -v '/$'biten çizgileri kaldırır /; yani, dizin adları. Maalesef, --file-typeseçenek POSIX tarafından belirtilmedi . Sürümünüz lsdesteklemiyorsa kullanın -F. Bu, bazı kişilerin can sıkıcı bulduğu yürütülebilir dosya adlarının sonunda --file-type bir de görüntülemesi dışında gibidir *. Bunları aşağıdakilerle ortadan kaldırabilirsiniz sed:

ls -dF -- source/** | sed -e '/\/$/d' -e 's/\*$//'

Tüm dosyalarla (ve yalnızca dosyalarla) bir şey yapmak istiyorsanız,

Kaynaktaki f için / **
yapmak
    [-f "$ f"] ise
    sonra
        Düz dosyalara uygulanacak komutları buraya ekleyin.
    fi
tamam

Notlar:

  • Bir lsterminale çıkış yapıldığında ve -l( l ong) modunda olmadığında, satır başına birden çok ad yazar (adlar çok uzun değilse). -1(Bir) belirterek veya çıktıyı bir dosyaya veya boruya yönlendirerek satır başına bir ad yazmaya zorlayabilirsiniz .
  • Muhtemelen gerçekten gerekmez --içinde lskimin içeriği oluşturduğunuz bir dizin listeleme ediyoruz beri komutları. *Bilinmeyen bir dizinde listeleme yaparken , ile başlayan dosya adlarına karşı koruma olarak kullanmalısınız -.
  • Çıktısını ayrıştırmaya çalışmayın ls.
  • globstarKabuk seçeneği POSIX tarafından tanımlanabilecek olmadığı görülüyor. (Aslında, POSIX'in herhangi bir kabuk seçeneğini tanıdığından emin değilim .) Bir bashizm gibi görünse de , dikkatli olun - bash'ın tüm sürümlerinde olmayabilir.
  • Alt dizinleri varsa fontsveya varsa images, **hepsini, özyineli olarak, aşağıya doğru listeler. Derinliği sınırlamanın bir (biraz bulanık ve güvenilmez) yolu

    ls -d --file-type -- source/** | grep -v '\(/.*\)\{3\}'
    

    üç veya daha fazla /karakter içeren satırları siler .

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.