各サブディレクトリ内のファイルの数


21

BASHコマンドで、ディレクトリの各サブディレクトリにあるファイルの数だけを一覧表示したいと思います。

ディレクトリ内など/tmpがありdir1dir2...私が見てみたいと思います:

`dir1` : x files 
`dir2` : x files ...

回答:


32

ファイルのみの再帰的なカウントが必要で、ディレクトリやその他のタイプは必要ない場合、次のようなものが機能するはずです。

find . -maxdepth 1 -mindepth 1 -type d | while read dir; do
  printf "%-25.25s : " "$dir"
  find "$dir" -type f | wc -l
done

また、「find:警告:-maxdepthオプションを非オプション引数-typeの後に指定しましたが、オプションは定位置ではありません(-maxdepthは、その前に指定されたテストとその後に指定されたテストに影響します。オプションを指定してください。他の議論の前に。」
jldupont 2012

2
これまでに与えられた両方の回答は、改行文字を含む名前のファイルが存在するというまれなケースで誤った結果をもたらします。あなたはそれをfind... -print0 | xargs -0....で処理することができます
スコット

@jldupont:深さ引数を´-type d´の前に移動します。私は回答を編集しました。
トール

はい、そしてこの素晴らしい解決策は外部変数をとらないので動作するという情報を追加させてくださいbash alias!!
構文エラー2014年

高速で、パイプsort -rn -k 2,2 -t$':'ラインでDESCリストを取得
Andre Figueiredo

14

この仕事は私をとても魅了し、自分で解決策を見つけたかったのです。それも、whileループを取らないとMAY実行速度に速くなります。言うまでもなく、トールの努力は私に物事を詳細に理解するのに大いに役立ちました。

これが私のものです:

find . -maxdepth 1 -mindepth 1 -type d -exec sh -c 'echo "{} : $(find "{}" -type f | wc -l)" file\(s\)' \;

見た目よりもはるかに強力であるため、理由は控えめに見えます。:-)

ただし、これを.bash_aliasesファイルに含める場合は、次のようにする必要があります。

alias somealias='find . -maxdepth 1 -mindepth 1 -type d -exec sh -c '\''echo "{} : $(find "{}" -type f | wc -l)" file\(s\)'\'' \;'

ネストされた単一引用符の扱いが非常に難しいことに注意してください。いいえ、引数に二重引用符を使用することはできませんsh -c


ディレクトリごとに/ bin / shを呼び出すので、速度は遅くなります。これはで確認できstrace -fc scriptます。ご使用のバージョンでは、システム呼び出しが約70%増加しています。短いコード:-)のための1
トール

1
これに触発されました。filecountでソート:find . -maxdepth 1 -mindepth 1 -type d -exec sh -c 'echo "$(find "{}" -type f | wc -l)" {}' \; | sort -nr
mnagel 2017年

7
find . -type f | cut -d"/" -f2 | uniq -c

現在のフォルダー内のフォルダーとファイルを、その下にあるファイルの数とともに一覧表示します。迅速で便利なIMO。(ファイルはカウント1で表示されます)。


1
それがどのように機能しているのかについて少し説明はどうですか?:)
C0deDaedalus 2018年

1
素晴らしいです、ありがとう!| sort -rnファイルの数でサブディレクトリをソートするために追加することができます。
Dennis Golomazov

1

再帰的にカウントしたいが、特定のディレクトリの直下にあるファイルのカウントだけが必要な場合は、findを使用するのが確実です。

ls dir1 | wc -l


私が持っている1000のディレクトリのそれぞれに対してこれを実行したくない...
jldupont

次に、xargsを使用します。ls -d */ | xargs -n1 ls | wc -l(ただし、既に機能している場合は、受け入れた答えを使用してください。これは、ただ今のところわかっていることです。)
jrajav

あなたの提案は何秒も結果を出さなかったのに対して、私が受け入れた答えはそうしました。
jldupont 2012

@jrajavこのアプローチは、空白が含まれるディレクトリでは完全に失敗します。これがfind重要な理由です。(おろか-print0xargs -0、すでに他の回答でスコットによって指摘)
でSyntaxError

1
find . -mindepth 1 -type d -print0 | xargs -0 -I{} sh -c 'printf "%4d : %s\n" "$(find {} -type f | wc -l)" "{}"'

サブディレクトリにあるファイルの数を数えて、このコマンドを使用する必要があることがよくあります。カウントが最初に表示されるようにします。


0

使用するもの...これにより、パラメーターとして指定したサブディレクトリー内のすべてのサブディレクトリーの配列が作成されます。すべてのサブディレクトリが処理されるまで、サブディレクトリとその同じサブディレクトリの数を出力します。

#!/bin/bash    
directories=($(/bin/ls -l $1 | /bin/grep "^d" | /usr/bin/awk -F" " '{print $9}'))

for item in ${directories[*]}
    do
        if [ -d "$1$item" ]; then
            echo "$1$item"
            /bin/ls $1$item | /usr/bin/wc -l
        fi
    done

0

このpythonコードを使用できます。実行してインタープリターを起動し、python3これを貼り付けます:

folder_path = '.'
import os, glob
for folder in sorted(glob.glob('{}/*'.format(folder_path))):
    print('{:}: {:>8,}'.format(os.path.split(folder)[-1], len(glob.glob('{}/*'.format(folder)))))

または、ネストされたカウントの再帰バージョン:

import os, glob
def nested_count(folder_path, level=0):
    for folder in sorted(glob.glob('{}/'.format(os.path.join(folder_path, '*')))):
        print('{:}{:}: {:,}'.format('    '*level, os.path.split(os.path.split(folder)[-2])[-1], len(glob.glob(os.path.join(folder, '*')))))
        nested_count(folder, level+1)
nested_count('.')

出力例:

>>> figures: 5
>>> misc: 1
>>> notebooks: 5
>>>     archive: 65
>>>     html: 12
>>>     py: 12
>>>     src: 14
>>> reports: 1
>>>     content: 6
>>> src: 1
>>>     html_download: 1
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.