ディレクトリ内のファイルタイプの再帰統計?


65

コンバージョンプロジェクトのウェブサイトスクレイプを行いました。そこにあるファイルの種類について、いくつかの統計を行いたいです。たとえば、400 .htmlファイル、100 .gifなどです。これを行う簡単な方法は何ですか?再帰的でなければなりません。

編集: maxschelpzigが投稿したスクリプトでは、私がスクレイプしたサイトのアーキテクチャのためにいくつかの問題が発生しています。一部のファイルは*.php?blah=blah&foo=barさまざまな引数を持つ名前であるため、すべてが一意であるとカウントされます。したがって、ソリューションは*.php*、いわば、すべて同じタイプであると考える必要があります。

回答:


96

あなたは使用することができますfindし、uniqこのため、例えば:

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

コマンドの説明

  • find すべてのファイル名を再帰的に出力します
  • sed すべてのファイル名からファイル拡張子までのプレフィックスを削除します
  • uniq ソートされた入力を想定
    • -c カウントを行います(ヒストグラムのように)。

同様のスクリプトがあります。シンプルで高速。
ルーフォエルマグーフォ

一部のファイルは*.php?blah=blah&foo=barさまざまな引数を持つ名前であるため、すべてが一意であるとカウントされます。探すように変更するにはどうすればよい*.php*ですか?
ユーザー394

3
あなたは、例えば、異なるsedの式を使用しようとすることができますsed 's/^.*\(\.[a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9]\).*$/\1/'
maxschlepzig

時間を割いて各部分の機能を説明していただきありがとうございます。同様のトピックに関する多くの回答では、この部分を省略しています。/ learning-to-fish
MechEthan

1
@ bela83、プルーンの亜種は短絡評価に依存しています。したがって、私の最初のバージョンfind -name '.*' -prune -o -type f -printは次のように評価.*します。.*また.、CWDにも一致するため、すべてが整理されます。つまり、findは最初のディレクトリにまで降下しません。おそらく、2年前のバージョンのfind振る舞いは異なっていました-または、それは当時の私に対する単なる見落としでした。とにかく、find -name '.*' -not -name . -prune -o -type f -printこれを修正します。
maxschlepzig

6

zshの場合:

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

このパターン **/?*.*は、現在のディレクトリとそのサブディレクトリにある拡張子を持つすべてのファイルに再帰的に一致します。グロブ修飾子は D聞かせてzshトラバースさえ隠しディレクトリを隠しファイルを検討し、.唯一の通常のファイルを選択します。歴史修飾子は、ファイル拡張子のみを保持します。print -rl1行に1つの一致を出力します。uniq -c連続する同一のアイテムをカウントします(glob結果は既にソートされています)。sort使用回数で拡張機能を並べ替える最後の呼び出し。


5

このワンライナーはかなり堅牢な方法のようです:

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

find . -type f -printf '%f\n'プリントなしのディレクトリとツリー内のすべての通常のファイルのベース名。これにより.sed正規表現にが含まれているディレクトリを心配する必要がなくなります。

sed -r -n 's/.+(\..*)$/\1/p'唯一その延長で入ってくるファイル名に置き換えられます。たとえば、に.somefile.extなり.extます。.+正規表現のイニシャルに注意してください。これにより、拡張子の前に少なくとも1文字必要な一致が生じ.ます。これにより.gitignore、名前がまったくないファイル名や拡張子「.gitignore」が必要なファイル名として扱われるのを防ぐことができます。ない場合は、交換してください.+.*

行の残りは、受け入れられた回答からのものです。

編集パレートチャート形式で適切にソートされたヒストグラムが必要な場合はsort、最後にもう1つ追加します。

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

ビルドされたLinuxソースツリーからのサンプル出力:

    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

このコンテンツで~/bin呼び出されるbashスクリプトをフォルダーに入れました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

どのディレクトリにいても、「exh」と入力するだけで、タブが自動補完され、次のように表示されます。

$ 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疑問符の後の部分のトリミングは、おそらく最後のコマンドの後の別のsedコマンドで簡単に行うことができます(私は試していません): sed 's/\?.*//'

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.