2009-03-10 29 views
17

Tôi muốn nhận danh sách thư mục ở cấp hiện tại (không bao gồm thư mục con của chúng) và chỉ cần in tên thư mục và số lượng tệp trong thư mục (tốt nhất là lọc * .jpg nếu có thể).Lệnh UNIX để liệt kê các thư mục có số lượng tệp

Điều này có thể xảy ra trong vỏ bash tiêu chuẩn không? ls -l in về tất cả mọi thứ nhưng file đếm :)

+2

Để người bình chọn gần: bash là một ngôn ngữ thực tế . – Bernard

Trả lời

21

tôi đã đi lên với điều này một:

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

Drop thứ hai -maxdepth 1 nếu tìm kiếm trong các thư mục cho các tập tin jpg nên đệ quy xem xét thư mục con . Lưu ý rằng chỉ xem xét tên của các tập tin. Bạn có thể đổi tên một tập tin, giấu nó là một hình ảnh jpg. Bạn có thể sử dụng lệnh file để làm một dự đoán về nội dung, thay vào đó (bây giờ, cũng tìm kiếm đệ quy):

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 

Tuy nhiên, đó là chậm hơn nhiều, vì nó có đọc một phần của các tập tin và cuối cùng giải thích những gì chúng chứa (nếu nó là may mắn, nó tìm thấy một id ma thuật ở đầu của tập tin). Các -mindepth 1 ngăn không cho nó in . (thư mục hiện tại) như một thư mục khác mà nó tìm kiếm.

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

Tôi sẽ nhập nhanh hơn từ dòng lệnh. :)

các đề xuất khác có cung cấp bất kỳ lợi thế thực nào sau đây không?

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


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

ví dụ: giáo viên muốn liệt kê các bức ảnh jpg của học sinh của mình. do đó, anh ta đặt lệnh trong/home và muốn liệt kê tất cả jpg trong các thư mục con đó để xác nhận chúng không chứa một số thứ gì đó :) ví dụ về giáo viên unix trước đó của tôi. ông biết những gì ông đã nói: p ppls đã cố gắng để ẩn pr0n của họ trong các tập tin bin: D –

+0

Điều đó chỉ in tổng số tệp, không phải là số cho mỗi thư mục. Tôi đã thực hiện nó ngay bây giờ, theo nhận xét ở trên. – DisgruntledGoat

+0

@DisgruntledGoat, tôi đã đọc sai câu hỏi của bạn. Xin lỗi vì điều đó. Giờ thì tôi đã hiểu. – m42

1

Bạn có thể làm điều đó mà không cần lệnh bên ngoài:

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

Hoặc bạn có thể sử dụng awk (nawk hoặc /usr/xpg4/bin/awk trên Solaris):

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

Tôi đã tìm thấy câu hỏi này sau r Tôi đã tìm ra kịch bản tương tự của riêng mình. Nó có vẻ phù hợp với điều kiện của bạn và rất linh hoạt vì vậy tôi nghĩ rằng tôi muốn thêm nó như là một câu trả lời.

Ưu điểm:

  • thể được nhóm lại để bất kỳ độ sâu (0 cho ., 1 thư mục con cấp độ đầu tiên, vv)
  • in ra khá
  • không vòng lặp, và chỉ có một find lệnh, vì vậy đó là một chút nhanh hơn trên các thư mục lớn
  • vẫn có thể được điều chỉnh để thêm các bộ lọc tùy chỉnh (maxdepth để làm cho nó không đệ quy, tên file mẫu)

mã thô:

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

bọc vào một chức năng và giải thích:

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 
} 

Tạo đầu ra như thế này:

$ fc 0 
1668 . 

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

Tất nhiên với số đầu tiên nó có thể được đường ống để sort:

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

Trên Solaris không có sẵn 'rev'. Bạn có thể sử dụng 'perl' thay vì giải pháp phổ quát: ' find -P. -type f | perl -lpe '$ _ = đảo ngược' | cắt -d/-f2- | perl -lpe '$ _ = đảo ngược' | cắt -d/-f1-2 | cắt -d/-f2- | sắp xếp | uniq -c' –

Các vấn đề liên quan