2009-03-10 12 views
17

Chcę uzyskać listę folderów na obecnym poziomie (bez podfolderów) i po prostu wydrukować nazwę folderu i liczbę plików w folderze (najlepiej filtrować do * .jpg jeśli to możliwe).Polecenie UNIX do wyświetlania folderów z liczbą plików

Czy jest to możliwe w standardowej powłoce bash? ls -l wydruki o wszystkim ale plik liczyć :)

+2

do osoby, która głosowała w pobliżu: bash jest rzeczywisty język . – Bernard

Odpowiedz

21

Doszedłem z tym jednym:

find -maxdepth 1 -type d | while read dir; do 
    count=$(find "$dir" -maxdepth 1 -iname \*.jpg | wc -l) 
    echo "$dir ; $count" 
done 

upuść sekund -maxdepth 1 Jeśli wyszukiwanie w katalogach dla plików jpg powinna być rekurencyjne uwzględnieniem podkatalogów . Zauważ, że uwzględnia tylko nazwy plików. Możesz zmienić nazwę pliku, ukrywając, że jest to obraz jpg. Można użyć komendy file zrobić przypuszczenie na temat zawartości, zamiast (obecnie również przeszukuje rekursywnie):

find -mindepth 1 -maxdepth 1 -type d | while read dir; do 
    count=$(find "$dir" -type f | xargs file -b --mime-type | 
      grep 'image/jpeg' | wc -l) 
    echo "$dir ; $count" 
done 

jednak, że jest o wiele wolniejszy, ponieważ musi odczytać część plików i ostatecznie zinterpretować to, co zawierają (jeśli ma szczęście, znajduje na początku pliku magiczny identyfikator). -mindepth 1 uniemożliwia wydrukowanie . (bieżącego katalogu) jako innego szukanego katalogu.

1
#!/bin/bash 
for dir in `find . -type d | grep -v "\.$"`; do 
echo $dir 
ls $dir/*.jpg | wc -l 
done; 
8

Kopalnia szybciej się wpisuje z wiersza poleceń. :)

czy inne sugestie oferują jakąkolwiek realną przewagę nad następującymi?

find -name '*.jpg' | wc -l    # recursive 


find -maxdepth 1 -name '*.jpg' | wc -l # current directory only 
+0

przykład: nauczyciel chce wyświetlić fotki JPG swoich uczniów. więc umieszcza polecenie w/home i chce wyświetlić listę wszystkich plików jpg w tych podkatalogach, aby potwierdzić, że nie zawierają one niektórych *** rzeczy :) z przykładu mojego poprzedniego nauczyciela systemu Unix. wiedział o czym mówi: p ppls próbowało ukryć swoje pr0n w plikach bin: D –

+0

To tylko drukuje całkowitą liczbę plików, a nie liczbę na folder. Zrobiłem to teraz i tak, zgodnie z powyższym komentarzem. – DisgruntledGoat

+0

@DisgruntledGoat, źle odczytałem twoje pytanie. Przepraszam za to. Teraz rozumiem. – m42

1

Można to zrobić bez poleceń zewnętrznych:

for d in */; do 
    set -- "$d"*.jpg 
    printf "%s: %d\n" "${d%/}" "$#" 
done 

lub użyć awk (nawk lub /usr/XPG4/bin/awk na Solaris):

printf "%s\n" */*jpg | 
    awk -F\/ 'END { 
    for (d in _) 
     print d ":",_[d] 
     } 
    { _[$1]++ }' 
9

Znalazłem to pytanie r Już wymyśliłem swój własny podobny scenariusz. Wydaje się pasować do twoich warunków i jest bardzo elastyczny, więc pomyślałem, że dodam to jako odpowiedź.

Zalety:

  • można podzielić na każdej głębokości (od 0 do 1, na . podkatalogów pierwszego stopnia, etc.)
  • wydruki wyjściowe dość
  • bez pętli, a tylko jeden find dowodzenia, więc jest to nieco szybciej na dużych katalogów
  • nadal można dostroić do dodawania własnych filtrów (maxdepth aby nierekursywnych, nazwa pliku wzór)

kod surowego:

find -P . -type f | rev | cut -d/ -f2- | rev | \ 
     cut -d/ -f1-2 | cut -d/ -f2- | sort | uniq -c 

owinięty w funkcji i wyjaśnione:

fc() { 
    # Usage: fc [depth >= 0, default 1] 
    # 1. List all files, not following symlinks. 
    #  (Add filters like -maxdepth 1 or -iname='*.jpg' here.) 
    # 2. Cut off filenames in bulk. Reverse and chop to the 
    #  first/(remove filename). Reverse back. 
    # 3. Cut everything after the specified depth, so that each line 
    #  contains only the relevant directory path 
    # 4. Cut off the preceeding '.' unless that's all there is. 
    # 5. Sort and group to unique lines with count. 

    find -P . -type f \ 
     | rev | cut -d/ -f2- | rev \ 
     | cut -d/ -f1-$((${1:-1}+1)) \ 
     | cut -d/ -f2- \ 
     | sort | uniq -c 
} 

Wytwarza wyjścia tak:

$ fc 0 
1668 . 

$ fC# depth of 1 is default 
    6 . 
    3 .ssh 
    11 Desktop 
    44 Downloads 
1054 Music 
550 Pictures 

oczywiście z numerem pierwszym mogą być odprowadzone do sort:

$ fc | sort 
    3 .ssh 
    6 . 
    11 Desktop 
    44 Downloads 
550 Pictures 
1054 Music 
+0

W systemie Solaris nie ma dostępnych "rev". Możesz użyć 'perl' zamiast uniwersalnego rozwiązania: ' find -P. -type f | perl -lpe '$ _ = reverse "| cut -d/-f2- | perl -lpe '$ _ = reverse "| cut -d/-f1-2 | cut -d/-f2- | sortuj uniq -c' –