web-dev-qa-db-ja.com

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

変換プロジェクトのWebサイトスクレイピングを行いました。そこにあるファイルのタイプについていくつか統計を作成したいと思います。たとえば、400 .htmlファイル、100 .gifなどです。これを行う簡単な方法は何ですか?再帰的でなければなりません。

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

72
user394

これにはfinduniqを使用できます。例:

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

コマンドの説明

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

Zshの場合:

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

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

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

_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'として扱われるのを防ぎます。そうでない場合は、_.+_を_.*_に置き換えます。

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

Edit:うまく並べ替えられたヒストグラムが Pareto chart 形式で必要な場合は、別のsortを終わり:

_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
_
5

私はexhistという名前の~/binフォルダにbashスクリプトを入れ、次の内容を含めました。

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

追伸疑問符の後の部分のトリミングは、おそらく最後のコマンドの後の別のsedコマンドで簡単に実行できるはずです(私は試していません):sed 's/\?.*//'

2
Zsolt Katona