dizinindeki dosya türlerinde özyinelemeli istatistikler?


65

Dönüşüm projesi için bir web sitesi hazırladım. Orada bulunan dosya türleri hakkında bazı istatistikler yapmak istiyorum - örneğin, 400 .htmldosya, 100 .gifvb. Bunu yapmanın kolay yolu nedir? Özyinelemeli olmalı.

Düzenleme: Maxschelpzig'in yayınladığı senaryo ile, kazıdığım sitenin mimarisi nedeniyle bazı problemlerim var. Dosyaların bazıları *.php?blah=blah&foo=barçeşitli argümanlara sahip isimdir , bu yüzden hepsini benzersiz olarak sayar. Dolayısıyla çözüm *.php*, tabiri caizse, aynı tipte olmak zorunda.

Yanıtlar:


96

Örneğin findve bunun uniqiçin kullanabilirsiniz :

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

Komut açıklaması

  • find tüm dosya adlarını tekrar tekrar yazdırır
  • sed dosya uzantısına kadar her dosya adından öneki siler
  • uniq sıralanmış girişi varsayar
    • -c saymayı yapar (histogram gibi).

Bende benzer bir senaryo var. Basit ve hızlı.
Rufo El Magufo

Dosyaların bazıları *.php?blah=blah&foo=barçeşitli argümanlara sahip isimdir , bu yüzden hepsini benzersiz olarak sayar. Aramak için nasıl değiştirebilirim *.php*?
kullanıcı394

3
Farklı bir sed ifadesi kullanmayı deneyebilirsiniz, örn.sed 's/^.*\(\.[a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9]\).*$/\1/'
maxschlepzig

Her bir bölümün ne yaptığını açıklamak için zaman ayırdığınız için teşekkür ederiz. Benzer konularda çok fazla cevap bu kısmı atlıyor. / Balık
avına

1
@ bela83, erik çeşitleri kısa devre değerlendirmesine dayanır - bu nedenle ilk sürümüm şöyle find -name '.*' -prune -o -type f -printdeğerlendirir: eğer dizin girişi eşleşirse o zaman budamayı erit, .*aksi takdirde bir dosya ise yazdır. Yana .*da maçları ., CWD'sindeki yani her şey yani bulmak bile ilk dizinin içine girer gelmez budanır. Belki de, 2 yıllık versiyonları findfarklı davranıyordu - ya da o zamanlar sadece bir nezaretti. Her neyse, bunu find -name '.*' -not -name . -prune -o -type f -printdüzeltir.
maxschlepzig

6

Zsh ile:

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

Desen **/?*.* ardışık tüm geçerli dizinde bir uzantısı olan dosyaları ve alt dizinleri ile eşleşir. Glob eleme D izin zshçapraz hatta gizli dizinleri ve gizli dosyaları düşünün .sadece normal dosyaları seçer. Tarih değiştirici sadece dosya uzantısı korur. print -rlHer satıra bir eşleşme basar. uniq -cardışık aynı öğeleri sayar (glob sonucu zaten sıralanır). Son çağrı sort, uzantıları kullanım sayısına göre sıralar.


5

Bu tek astar oldukça sağlam bir yöntem gibi görünüyor:

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

find . -type f -printf '%f\n'Baskılar hiçbir dizinleri ile ağaçtaki her düzenli dosyanın basename. Yani olabilecek dizinleri hakkında endişe ortadan kaldırır .sizin de onları 's sedregex.

sed -r -n 's/.+(\..*)$/\1/p'Sadece uzantılı gelen dosya adı değiştirir. Örneğin, .somefile.extolur .ext. .+Regex'te ilk olanı not edin ; bu, uzantıdan önce en az bir karakter gerektiren herhangi bir eşleşmeyle sonuçlanır .. Bu, dosya adlarının .gitignoreadının olmadığı gibi davranılmasını ve '.gitignore' uzantısını engeller; bu da muhtemelen istediğiniz şeydir. Değilse, yerini .+bir ile .*.

Hattın geri kalanı kabul edilen cevaptan geliyor.

Düzenleme : Pareto grafik biçiminde güzelce sıralanmış bir histogram istiyorsanız sort, sonuna bir tane daha ekleyin :

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

Yerleşik bir Linux kaynak ağacından örnek çıktı:

    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

Bu içerikle ~/binadlandırılan klasörüme bash betiği koydum exhist:

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

Hangi dizinde olursam olalım, sadece 'exh' yazarım, sekme onu otomatik olarak tamamlar ve şöyle bir şey görürüm:

$ 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 Soru işaretinden sonra parçanın kırpılması, muhtemelen sonuncusundan sonra başka bir sed komutuyla yapılması kolay olmalıdır (denemedim): sed 's/\?.*//'

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.