statistik rekursif tentang jenis file dalam direktori?

65

Saya melakukan pengikisan situs web untuk proyek konversi. Saya ingin melakukan beberapa statistik pada jenis file di sana - misalnya, 400 .htmlfile, 100 .gif, dll. Apa cara mudah untuk melakukan ini? Itu harus bersifat rekursif.

Sunting: Dengan skrip yang diposting maxschelpzig, saya mengalami beberapa masalah karena arsitektur situs yang saya memo. Beberapa file memiliki nama *.php?blah=blah&foo=bardengan berbagai argumen, jadi semuanya dianggap unik. Jadi solusinya perlu mempertimbangkan *.php*semua dari jenis yang sama, sehingga untuk berbicara.

pengguna394
sumber

Jawaban:

96

Anda dapat menggunakan finddan uniquntuk ini, misalnya:

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

Penjelasan perintah

  • find secara rekursif mencetak semua nama file
  • sed menghapus dari setiap nama file awalan sampai ekstensi file
  • uniq mengasumsikan input yang diurutkan
    • -c melakukan penghitungan (seperti histogram).
maxschlepzig
sumber
Saya memiliki skrip yang serupa. Sederhana dan cepat.
Rufo El Magufo
Beberapa file memiliki nama *.php?blah=blah&foo=bardengan berbagai argumen, jadi semuanya dianggap unik. Bagaimana saya bisa memodifikasinya untuk dicari *.php*?
user394
3
Anda dapat mencoba menggunakan ekspresi sed yang berbeda, misalnyased 's/^.*\(\.[a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9]\).*$/\1/'
maxschlepzig
Terima kasih telah meluangkan waktu untuk menjelaskan apa yang setiap porsi lakukan. Begitu banyak jawaban pada topik yang sama melewati bagian ini. / learning-to-fish
MechEthan
1
@ bela83, varian prune bergantung pada evaluasi hubung singkat - dengan demikian, versi pertamaku find -name '.*' -prune -o -type f -printdievaluasi seperti: jika entri direktori cocok .*maka pangkas, jika tidak, itu adalah file kemudian cetak. Karena .*juga cocok ., yaitu CWD, semuanya dipangkas, yaitu menemukan bahkan tidak turun ke direktori pertama. Mungkin, versi 2 tahun findberperilaku berbeda - atau itu hanya kekhilafan saya, saat itu. Bagaimanapun, find -name '.*' -not -name . -prune -o -type f -printperbaiki ini.
maxschlepzig
6

Dengan zsh:

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

The Pola **/?*.* cocok dengan semua file yang memiliki ekstensi, di direktori saat ini dan subdirektorinya secara rekursif. The kualifikasi gumpal D biarkan zshmelintasi direktori bahkan tersembunyi dan mempertimbangkan file tersembunyi, .memilih hanya file biasa. The pengubah sejarah mempertahankan hanya ekstensi file. print -rlmencetak satu kecocokan per baris. uniq -cmenghitung item identik berturut-turut (hasil gumpalan sudah diurutkan). Panggilan terakhir untuk sortmengurutkan ekstensi dengan menggunakan hitungan.

Gilles 'SANGAT berhenti menjadi jahat'
sumber
5

Satu garis ini tampaknya merupakan metode yang cukup kuat:

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

The find . -type f -printf '%f\n'cetakan yang basename setiap file biasa di pohon, tanpa direktori. Itu menghilangkan harus khawatir tentang direktori yang mungkin ada .di dalamnya di sedregex Anda .

The sed -r -n 's/.+(\..*)$/\1/p'menggantikan nama file yang masuk dengan hanya ekstensi. Misalnya, .somefile.extmenjadi .ext. Catat inisial .+dalam regex; ini menghasilkan setiap kecocokan yang membutuhkan setidaknya satu karakter sebelum ekstensi .. Ini mencegah nama file seperti .gitignoretidak diperlakukan sama sekali tanpa nama dan ekstensi '.gitignore', yang mungkin Anda inginkan. Jika tidak, ganti .+dengan a .*.

Sisa kalimat berasal dari jawaban yang diterima.

Sunting : Jika Anda ingin histogram yang diurutkan dengan baik dalam format bagan Pareto , tambahkan saja yang lain sortke akhir:

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

Contoh output dari pohon sumber Linux yang dibangun:

    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
Gary R. Van Sickle
sumber
1

Saya telah memasukkan skrip bash ke ~/binfolder saya yang dipanggil exhistdengan konten ini:

#!/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

Di direktori mana pun saya berada, saya cukup ketik 'exh', tab pelengkap otomatis, dan saya melihat sesuatu seperti ini:

$ 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 Memotong bagian setelah tanda tanya harus mudah dilakukan dengan perintah sed lain mungkin setelah yang terakhir (saya belum mencobanya): sed 's/\?.*//'

Zsolt Katona
sumber