thống kê đệ quy về các loại tập tin trong thư mục?


65

Tôi đã làm một trang web cạo cho một dự án chuyển đổi. Tôi muốn làm một số thống kê về các loại tệp trong đó - ví dụ: 400 .htmltệp, 100 .gif, v.v ... Cách dễ dàng để làm điều này là gì? Nó phải được đệ quy.

Chỉnh sửa: Với tập lệnh mà maxschelpzig đã đăng, tôi gặp một số vấn đề do kiến ​​trúc của trang web tôi đã xử lý. Một số tệp có tên *.php?blah=blah&foo=barvới các đối số khác nhau, vì vậy nó tính tất cả chúng là duy nhất. Vì vậy, giải pháp cần phải xem xét *.php*là tất cả cùng loại, để nói.

Câu trả lời:


96

Bạn có thể sử dụng finduniqcho việc này, ví dụ:

$ find . -type f | sed 's/.*\.//' | sort | uniq -c
   16 avi
   29 jpg
  136 mp3
    3 mp4

Lệnh giải thích

  • find đệ quy in tất cả tên tập tin
  • sed xóa từ mọi tên tệp tiền tố cho đến khi mở rộng tập tin
  • uniq giả định đầu vào được sắp xếp
    • -c không đếm (như một biểu đồ).

Tôi có một kịch bản tương tự. Đơn giản và nhanh chóng.
Rufo El Magufo

Một số tệp có tên *.php?blah=blah&foo=barvới các đối số khác nhau, vì vậy nó tính tất cả chúng là duy nhất. Làm thế nào tôi có thể sửa đổi nó để tìm kiếm *.php*?
dùng394

3
Bạn có thể thử sử dụng một biểu sed khác nhau, ví dụ:sed 's/^.*\(\.[a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9]\).*$/\1/'
maxschlepzig

Cảm ơn bạn đã dành thời gian để giải thích những gì từng phần. Vì vậy, nhiều câu trả lời về các chủ đề tương tự bỏ qua phần này. / học để cá
MechEthan

1
@ bela83, các biến thể cắt tỉa dựa trên đánh giá ngắn mạch - do đó, phiên bản đầu tiên của tôi find -name '.*' -prune -o -type f -printđánh giá như sau: nếu mục nhập thư mục khớp .*thì cắt tỉa nó, nếu không thì là tệp rồi in ra. Vì .*cũng khớp ., tức là CWD, mọi thứ đều được cắt tỉa, tức là find thậm chí không rơi vào thư mục đầu tiên. Có lẽ, phiên bản 2 tuổi của findhành vi khác nhau - hoặc đó chỉ là sự giám sát của tôi, hồi đó. Nhưng dù sao, find -name '.*' -not -name . -prune -o -type f -printsửa cái này.
maxschlepzig

6

Với zsh:

print -rl -- **/?*.*(D.:e) | uniq -c |sort -n

Các mô hình **/?*.* phù hợp với tất cả các file mà có một phần mở rộng, trong thư mục hiện hành và thư mục con của nó một cách đệ quy. Vòng loại toàn cầu D cho phép duyệt zshqua các thư mục bị ẩn và xem xét các tệp bị ẩn, .chỉ chọn các tệp thông thường. Công cụ sửa đổi lịch sử chỉ giữ lại phần mở rộng tập tin. print -rlin một trận đấu trên mỗi dòng. uniq -cđếm các mục giống hệt nhau liên tiếp (kết quả toàn cầu đã được sắp xếp). Cuộc gọi cuối cùng để sortsắp xếp các phần mở rộng theo số lượng sử dụng.


5

Điều này một lót có vẻ là một phương pháp khá mạnh mẽ:

find . -type f -printf '%f\n' | sed -r -n 's/.+(\..*)$/\1/p' | sort | uniq -c

Bản find . -type f -printf '%f\n'in tên cơ sở của mọi tệp thông thường trong cây, không có thư mục. Điều đó giúp loại bỏ việc phải lo lắng về các thư mục có thể có .trong thư mục của bạn sed.

Việc sed -r -n 's/.+(\..*)$/\1/p'thay thế tên tệp đến chỉ với phần mở rộng của nó. Ví dụ, .somefile.exttrở thành .ext. Lưu ý ban đầu .+trong regex; điều này dẫn đến bất kỳ trận đấu nào cần ít nhất một ký tự trước phần mở rộng .. Điều này ngăn tên tập tin như .gitignorebị coi là không có tên nào cả và phần mở rộng '.gitignore', đây có thể là điều bạn muốn. Nếu không, thay thế .+bằng a .*.

Phần còn lại của dòng là từ câu trả lời được chấp nhận.

Chỉnh sửa : Nếu bạn muốn một biểu đồ được sắp xếp độc đáo ở định dạng biểu đồ Pareto , chỉ cần thêm một biểu đồ khác sortvào cuối:

find . -type f -printf '%f\n' | sed -r -n 's/.+(\..*)$/\1/p' | sort | uniq -c | sort -bn

Đầu ra mẫu từ cây nguồn Linux được xây dựng:

    1 .1992-1997
    1 .1994-2004
    1 .1995-2002
    1 .1996-2002
    1 .ac
    1 .act2000
    1 .AddingFirmware
    1 .AdvancedTopics
    [...]
 1445 .S
 2826 .o
 2919 .cmd
 3531 .txt
19290 .h
23480 .c

1

Tôi đã đặt một tập lệnh bash vào ~/binthư mục của tôi được gọi exhistvới nội dung này:

#!/bin/bash

for d in */ ; do
        echo $d
        find $d -type f | sed -r 's/.*\/([^\/]+)/\1/' | sed 's/^[^\.]*$//' | sed -r 's/.*(\.[^\.]+)$/\1/' | sort | uniq -c | sort -nr
#       files only      | keep filename only          | no ext -> '' ext   | keep part after . (i.e. ext) | count          | sort by count desc
done

Bất cứ thư mục nào tôi đang ở, tôi chỉ cần gõ 'shout', tab tự động hoàn thành nó và tôi thấy một cái gì đó như thế này:

$ exhist
src/
      7 .java
      1 .txt
target/
     42 .html
     10 .class
      4 .jar
      3 .lst
      2 
      1 .xml
      1 .txt
      1 .properties
      1 .js
      1 .css

PS Cắt bớt phần sau dấu chấm hỏi nên đơn giản để thực hiện với một lệnh sed khác có lẽ sau câu cuối cùng (tôi chưa thử): sed 's/\?.*//'

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.