Hitungan file di setiap sub-direktori


21

Saya ingin perintah BASH untuk mencantumkan hanya jumlah file di setiap subdirektori direktori.

Misalnya dalam direktori /tmpada dir1, dir2, ... saya ingin lihat:

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

Jawaban:


32

Dengan anggapan Anda hanya menginginkan jumlah file rekursif, bukan direktori dan tipe lainnya, sesuatu seperti ini seharusnya berfungsi:

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

Juga, saya mendapatkan "find: warning: Anda telah menentukan opsi -maxdepth setelah argumen non-opsi -type, tetapi opsi tidak bersifat posisional (-maxdepth memengaruhi tes yang ditentukan sebelum serta yang ditentukan setelahnya). Silakan tentukan opsi sebelum argumen lain. "
jldupont

2
Kedua jawaban yang diberikan sejauh ini akan memberikan hasil yang salah dalam kasus yang tidak mungkin ada file yang namanya menyertakan karakter baris baru. Anda dapat mengatasinya dengan find... -print0 | xargs -0....
Scott

@ jldupont: pindahkan argumen mendalam sebelum ´-type d´, saya telah mengedit jawabannya.
Thor

Ya, dan izinkan saya menambahkan informasi bahwa solusi yang sangat baik ini tidak akan mengambil variabel eksternal dan karenanya akan bekerja dengan bash alias!!
syntaxerror

cepat, dan perpipaan sort -rn -k 2,2 -t$':'Anda mendapatkan daftar DESC
Andre Figueiredo

14

Tugas ini sangat memesona saya sehingga saya ingin mencari solusi sendiri. Bahkan tidak memerlukan waktu beberapa saat dan MUNGKIN lebih cepat dalam kecepatan eksekusi. Tak perlu dikatakan, upaya Thor banyak membantu saya untuk memahami hal-hal secara rinci.

Jadi ini milik saya:

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

Itu terlihat sederhana karena suatu alasan, karena jauh lebih kuat daripada kelihatannya. :-)

Namun, jika Anda bermaksud untuk memasukkan ini ke dalam .bash_aliasesfile Anda , itu harus terlihat seperti ini:

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

Perhatikan penanganan kutipan tunggal bersarang yang sangat rumit . Dan tidak, tidak mungkin menggunakan tanda kutip ganda untuk sh -cargumen.


Itu lebih lambat karena memanggil / bin / sh untuk setiap direktori. Anda dapat memeriksanya dengan strace -fc script. Versi Anda membuat sekitar 70% lebih banyak panggilan sistem. +1 untuk kode yang lebih pendek :-)
Thor

1
terinspirasi oleh ini; diurutkan berdasarkan filecount:find . -maxdepth 1 -mindepth 1 -type d -exec sh -c 'echo "$(find "{}" -type f | wc -l)" {}' \; | sort -nr
mnagel

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

Daftar folder dan file di folder saat ini dengan jumlah file yang ditemukan di bawah. IMO cepat dan bermanfaat. (file tampil dengan hitungan 1).


1
Bagaimana dengan sedikit penjelasan tentang cara kerjanya? :)
C0deDaedalus

1
keren terima kasih! Anda mungkin ingin menambahkan | sort -rnuntuk mengurutkan subdir berdasarkan jumlah file.
Dennis Golomazov

1

Menggunakan find jelas merupakan cara untuk pergi jika Anda ingin menghitung secara rekursif, tetapi jika Anda hanya ingin menghitung file secara langsung di bawah direktori tertentu:

ls dir1 | wc -l


Saya tidak ingin melakukan ini untuk masing-masing dari 1000 direktori yang saya dapatkan di sana ...
jldupont

Kemudian gunakan xargs. ls -d */ | xargs -n1 ls | wc -l(Namun, gunakan jawaban yang Anda terima jika sudah berfungsi! Ini hanya Dan Sekarang Anda Tahu.)
jrajav

proposal Anda tidak menunjukkan hasil apa pun dalam banyak detik sedangkan jawaban yang saya terima lakukan.
jldupont

@jrajav pendekatan ini benar-benar gagal untuk direktori dengan spasi putih di dalamnya. Inilah mengapa findsangat penting. (Apalagi -print0dan xargs -0, sudah ditunjukkan oleh Scott dalam jawaban lain)
sintaks

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

Saya sering perlu menghitung jumlah file dalam sub-direktori saya dan menggunakan perintah ini. Saya lebih suka penghitungan muncul terlebih dahulu.


0

Apa yang saya gunakan ... Ini membuat array dari semua subdirektori dalam yang Anda berikan sebagai parameter. Cetak subdirektori dan jumlah subdirektori yang sama hingga semua subdirektori diproses.

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

Anda bisa menggunakan kode python ini. Boot penerjemah dengan menjalankan python3dan menempelkan ini:

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)))))

Atau versi rekursif untuk penghitungan bersarang:

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('.')

Contoh output:

>>> figures: 5
>>> misc: 1
>>> notebooks: 5
>>>     archive: 65
>>>     html: 12
>>>     py: 12
>>>     src: 14
>>> reports: 1
>>>     content: 6
>>> src: 1
>>>     html_download: 1
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.