web-dev-qa-db-ja.com

各ディレクトリ内のファイルの数を数える方法は?

私はすべてのディレクトリをリストすることができます

find ./ -type d

次のコマンドを使用して、各ディレクトリの内容をリストし、各ディレクトリ内のファイルの数をカウントしようとしました

find ./ -type d | xargs ls -l | wc -l

しかし、これは以下によって返された行の合計数を合計しました

find ./ -type d | xargs ls -l

各ディレクトリ内のファイルの数を数える方法はありますか?

83
user784637

GNUが見つかったと仮定して、ディレクトリを見つけ、残りをbashに任せる:

find . -type d -print0 | while read -d '' -r dir; do
    files=("$dir"/*)
    printf "%5d files in directory %s\n" "${#files[@]}" "$dir"
done
88
glenn jackman

これにより、現在のディレクトリレベルのディレクトリごとのファイル数が出力されます。

du -a | cut -d/ -f2 | sort | uniq -c | sort -nr
131

すべてのファイルを検索し、ファイル名を削除し、各ファイルのディレクトリ名のみを含む行を残して、各ディレクトリが表示される回数をカウントするように調整できます。

find . -type f |
sed 's%/[^/]*$%%' |
sort |
uniq -c

これで唯一の落とし穴は、改行文字を含むファイル名またはディレクトリ名がある場合です。ファイル名やディレクトリ名の改行について本当に心配する必要がある場合は、それらを見つけて、改行を含まないように修正することをお勧めします(そして、その方法の誤りについて、有罪関係者に静かに説得します)。


現在のディレクトリの各サブディレクトリ内のファイルの数に興味があり、サブディレクトリ内のファイルとそのすぐ下のサブディレクトリ内のファイルを数える場合は、sedコマンドを印刷に適応させます最上位ディレクトリのみ:

find . -type f |
sed -e 's%^\(\./[^/]*/\).*$%\1%' -e 's%^\.\/[^/]*$%./%' |
sort |
uniq -c

最初のパターンは、名前の始まり、ドット、スラッシュ、次のスラッシュまでの名前、およびスラッシュをキャプチャし、行を最初の部分だけで置き換えます。

./dir1/dir2/file1

に置き換えられます

./dir1/

2番目の置換は、現在のディレクトリに直接ファイルをキャプチャします。末尾にスラッシュはありません。これらは./に置き換えられます。ソートとカウントは、名前の数だけで機能します。

14

これを行う1つの方法を次に示しますが、おそらく最も効率的ではありません。

find -type d -print0 | xargs -0 -n1 bash -c 'echo -n "$1:"; ls -1 "$1" | wc -l' --

このような出力を提供します。ディレクトリ名の後に、そのディレクトリ内のエントリの数が続きます。出力カウントには、必要でないディレクトリエントリも含まれることに注意してください。

./c/fa/l:0
./a:4
./a/c:0
./a/a:1
./a/a/b:0
12
Austin Phillips

他のすべてのソリューションには、何らかの欠点があります。

find -type d -readable -exec sh -c 'printf "%s " "$1"; ls -1UA "$1" | wc -l' sh {} ';'

説明:

  • -type d:ディレクトリに興味があります。
  • -readablepossibleの場合にのみ、それらのファイルを一覧表示します。 findは、ディレクトリ内でさらにディレクトリを検索しようとするとエラーを出力しますが、これにより、-execが呼び出されないことに注意してください。
  • -exec sh -c BLAH sh {} ';':各ディレクトリに対して、$0shに設定し、$1をファイル名に設定して、このスクリプトフラグメントを実行します。
  • printf "%s " "$1":移植性のある最小限のディレクトリ名を出力し、その後に改行ではなくスペースのみを出力します。
  • ls -1UA:ファイルを1行に1つずつディレクトリ順にリストします(パイプのストールを避けるため)のみ特別なディレクトリ.および..を除きます
  • wc -l:行をカウントします
7
o11c
find . -type f | cut -d/ -f2 | sort | uniq -c
  • find. -type fは、タイプファイルのすべてのアイテムを検索します
  • cut -d/ -f2で特定のフォルダーを切り取ります
  • sortは、フォルダー名のリストをソートします
  • uniq -cは、各フォルダー名がカウントされた回数を返します
6
DCZ

これは、findの代わりにlsをループすることでも実行できます。

for f in */; do echo "$f -> $(ls $f | wc -l)"; done

説明:

for f in */;-すべてのディレクトリをループします

do echo "$f ->-各ディレクトリ名を出力します

$(ls $f | wc -l)-このディレクトリのlsを呼び出して行を数える

4
Sixhobbits

Sebastian's のわずかに変更されたバージョンは、findの代わりにduを使用して回答します(duが実行する必要があり、使用されないファイルサイズ関連のオーバーヘッドを除外します) :

 find ./ -mindepth 2 -type f | cut -d/ -f2 | sort | uniq -c | sort -nr

-mindepth 2パラメーターは、現在のディレクトリ内のファイルを除外するために使用されます。削除すると、次のような行が表示されます。

  234 dir1
  123 dir2
    1 file1
    1 file2
    1 file3
      ...
    1 fileN

duベースのバリアントと同様)

現在のディレクトリ内のファイルもカウントする必要がある場合は、この拡張バージョンを使用してください。

{ find ./ -mindepth 2 -type f | cut -d/ -f2 | sort && find ./ -maxdepth 1 -type f | cut -d/ -f1; } | uniq -c | sort -nr

出力は次のようになります。

  234 dir1
  123 dir2
   42 .
3
Yoory N.

これにより、ディレクトリ名に続いてディレクトリ内のファイル数が返されます。

findfiles() {
    echo "$1" $(find "$1" -maxdepth 1 -type f | wc -l)
}

export -f findfiles

find ./ -type d -exec bash -c 'findfiles "$0"' {} \;

出力例:

./ 6
./foo 1
./foo/bar 2
./foo/bar/bazzz 0
./foo/bar/baz 4
./src 4

export -fが必要なのは、find-exec引数は、bashを明示的に呼び出さない限りbash関数の実行を許可せず、現在のスコープで定義された関数を新しい明示的にシェル。

2
Tuxdude

見つける 。 -type f -printf '%h\n' |並べ替え| uniq -c

例えば:

  5 .
  4 ./aln
  5 ./aln/iq
  4 ./bs
  4 ./ft
  6 ./hot
1
Giddy

@ glenn jackman's answer と@pcarvalhoのanswer(コメントリストでは、文字 ' ` '(バックティック))。

私のスクリプトは、パスを引数として受け入れ、ディレクトリリストをls -lとしてソートできます。また、「ファイル名のスペース」の問題を処理できます

#!/bin/bash
OLD_IFS="$IFS"
IFS=$'\n'
for dir in $(find $1 -maxdepth 1 -type d | sort); 
do
    files=("$dir"/*)
    printf "%5d,%s\n" "${#files[@]}" "$dir"
done
FS="$OLD_IFS"

Stackoverflowでの私の最初の答え、そしてそれが誰かを助けることができることを願っています^ _ ^

1
vacing

将来のリマインダーのために、私はここに住んでいます

ls |parallel 'echo {} && ls {}|wc -l'
1
emanuele

これにより、全体的なカウントが得られます。

for file in */; do echo "$file -> $(ls $file | wc -l)"; done | cut -d ' ' -f 3| py --ji -l 'numpy.sum(l)'

超高速の奇跡コマンド。ファイルを再帰的に走査して、ディレクトリ内の画像の数をカウントし、画像の拡張子で出力を整理します。

find . -type f | sed -e 's/.*\.//' | sort | uniq -c | sort -n | grep -Ei '(tiff|bmp|jpeg|jpg|png|gif)$'

クレジット: https://unix.stackexchange.com/a/386135/35498

0
tsveti_iko

特定のタイプのファイルを再帰的に見つける簡単な方法。この場合、現在のディレクトリ内のすべてのフォルダーの.jpgファイル:

find . -name *.jpg -print | wc -l

0
Rex Barker

ここで他のいくつかを試してみましたが、ファイルだけが必要なときにファイルカウントにサブフォルダーが含まれてしまいました。これは、現在のフォルダー内の各サブフォルダーについて、サブフォルダーを含まないファイル数で./folder/path<tab>nnnを出力します。

for d in `find . -type d -print` 
do 
  echo -e "$d\t$(find $d -maxdepth 1 -type f -print | wc -l)"
done
0
sthames42