Bagaimana cara menghitung semua file secara rekursif melalui direktori

47

Saya ingin melihat berapa banyak file dalam subdirektori untuk mencari tahu di mana semua penggunaan inode pada sistem. Sepertinya saya akan melakukan ini untuk penggunaan ruang

du -sh /*

yang akan memberi saya ruang yang digunakan dalam direktori dari root, tetapi dalam hal ini saya ingin jumlah file, bukan ukurannya.

xenoterracide
sumber
Lihat juga menghitung secara rekursif semua file dalam direktori , Menghitung file di setiap direktori? di SU.
Gilles 'SANGAT berhenti menjadi jahat'
Saya pikir "berapa banyak file dalam subdirektori di sana subdirektori" adalah konstruksi yang membingungkan. Jika lebih jelas menyatakan apa yang Anda inginkan, Anda mungkin mendapatkan jawaban yang sesuai dengan tagihan.
Steven D
@ Seven merasa bebas untuk menulis ulang ... Saya pikir contoh saya du -sh /*membuatnya cukup jelas bagaimana saya ingin hitungan bekerja. hal yang sama, hitung saja file bukan byte.
xenoterracide
Seperti yang Anda sebutkan penggunaan inode, saya tidak mengerti apakah Anda ingin menghitung jumlah file atau jumlah inode yang digunakan. Keduanya berbeda ketika ada tautan keras di sistem file. Sebagian besar, jika tidak semua, jawaban memberikan jumlah file. Jangan menggunakannya pada disk cadangan Apple Time Machine.
mouviciel
@ mouviciel ini tidak digunakan pada disk cadangan, dan ya saya kira mereka mungkin berbeda, tetapi di lingkungan saya ada sangat sedikit hardlink, secara teknis saya hanya perlu merasakannya. mencari tahu di mana seseorang membakar kuota inode di sana.
xenoterracide

Jawaban:

60
find -maxdepth 1 -type d | while read -r dir; do printf "%s:\t" "$dir"; find "$dir" -type f | wc -l; done

Berkat Gilles dan xenoterracide untuk perbaikan keamanan / kompatibilitas.

Bagian pertama: find -maxdepth 1 -type dakan mengembalikan daftar semua direktori di direktori kerja saat ini. Ini disalurkan ke ...

Bagian kedua: while read -r dir; domemulai loop sementara - selama pipa yang masuk ke saat terbuka (yang sampai seluruh daftar direktori dikirim), perintah baca akan menempatkan baris berikutnya ke dalam variabel "dir". Lalu itu berlanjut ...

Bagian ketiga: printf "%s:\t" "$dir";akan mencetak string dalam "$ dir" (yang memegang salah satu nama direktori) diikuti oleh tab.

Bagian keempat: find "$dir -f file"membuat daftar semua file di dalam nama direktori yang disimpan dalam "$ dir". Daftar ini dikirim ke ..

Bagian kelima: wc -l;menghitung jumlah baris yang dikirim ke input standarnya.

Bagian terakhir: donecukup akhiri loop sementara.

Jadi kami mendapatkan daftar semua direktori di direktori saat ini. Untuk masing-masing direktori tersebut, kami membuat daftar semua file di dalamnya sehingga kami dapat menghitung semuanya menggunakan wc -l. Hasilnya akan terlihat seperti:

./dir1: 234
./dir2: 11
./dir3: 2199
...
Shawn J. Goff
sumber
Selalu gunakan read -rsebagai readbackslashes memperlakukan polos khusus. Kemudian echo -en "$dir:\t"akan kembali memotong backslash; perbaikan sederhana adalah menggunakan printf '%s:\t' "$dir"sebagai gantinya. Selanjutnya, $dirharus "$dir"( selalu menggunakan tanda kutip ganda di sekitar substitusi variabel ).
Gilles 'SO- stop being evil'
dimodifikasi per saran @Gilesfind -maxdepth 1 -type d | while read -r dir; do printf "%s:\t" "$dir"; find "$dir" | wc -l; done
xenoterracide
2
Saya menambahkan sort -n -r -k2di akhir ini, untuk banyak direktori, sehingga saya tahu di mana penggunaan terbanyak
xenoterracide
Bagian keempat: find "$ dir" membuat daftar semua file di dalam nama direktori yang disimpan dalam "$ dir". Anda lupa menambahkan -type funtuk membuatnya daftar file:find -maxdepth 1 -type d | while read -r dir; do printf "%s:\t" "$dir"; find "$dir" -type f | wc -l; done
Krzysztof Boduch
@ krzysiek-boduch Terima kasih! Saya memperbarui jawabannya.
Shawn J. Goff
15

Coba find . -type f | wc -l, ini akan menghitung semua file dalam direktori saat ini serta semua file dalam subdirektori. Perhatikan bahwa semua direktori tidak akan dihitung sebagai file, hanya file biasa yang melakukannya.

herohuyongtao
sumber
13

Berikut adalah kompilasi dari beberapa perintah daftar yang berguna (di-hash ulang berdasarkan kode pengguna sebelumnya):

Daftar folder dengan jumlah file:

find -maxdepth 1 -type d | sort | while read -r dir; do n=$(find "$dir" -type f | wc -l); printf "%4d : %s\n" $n "$dir"; done

Daftar folder dengan jumlah file non-nol:

find -maxdepth 1 -type d | sort | while read -r dir; do n=$(find "$dir" -type f | wc -l); if [ $n -gt 0 ]; then printf "%4d : %s\n" $n "$dir"; fi; done

Daftar folder dengan jumlah sub-folder:

find -maxdepth 1 -type d | sort | while read -r dir; do n=$(find "$dir" -type d | wc -l); let n--; printf "%4d : %s\n" $n "$dir"; done

Daftar folder dengan jumlah sub-folder bukan nol:

find -maxdepth 1 -type d | sort | while read -r dir; do n=$(find "$dir" -type d | wc -l); let n--; if [ $n -gt 0 ]; then printf "%4d : %s\n" $n "$dir"; fi; done

Daftar folder kosong:

find -maxdepth 1 -type d | sort | while read -r dir; do n=$(find "$dir" | wc -l); let n--; if [ $n -eq 0 ]; then printf "%4d : %s\n" $n "$dir"; fi; done

Daftar folder yang tidak kosong dengan jumlah konten:

find -maxdepth 1 -type d | sort | while read -r dir; do n=$(find "$dir" | wc -l); let n--; if [ $n -gt 0 ]; then printf "%4d : %s\n" $n "$dir"; fi; done
DolphinDream
sumber
Dan btw .. jika Anda ingin memiliki output dari salah satu perintah daftar ini diurutkan berdasarkan jumlah item .. pipa perintah menjadi semacam: "a-list-command" | sort -n
DolphinDream
12

Mencoba:

find /path/to/start/at -type f -print | wc -l

sebagai titik awal, atau jika Anda benar-benar hanya ingin mengulang melalui subdirektori direktori (dan lewati file di direktori tingkat atas itu)

find `find /path/to/start/at -mindepth 1 -maxdepth 1 -type d -print` -type f -print | wc -l
Cry Havok
sumber
+1 untuk sesuatu | wc-l ... jumlah kata adalah alat kecil yang bagus
Johan
ya tapi ini hanya melakukan 1 direktori .... Saya ingin mendapatkan hitungan untuk semua direktori dalam direktori, dan saya tidak ingin menjalankannya secara terpisah setiap kali ... tentu saja saya kira saya bisa menggunakan loop ... tapi aku malas.
xenoterracide
findbekerja secara rekursif melalui semua sub direktori secara default. Jika Anda ingin itu berfungsi di banyak lokasi, Anda bisa menentukan semuanya di antara finddan -type.
Didier Trosset
yang kedua tentu tidak berhasil .... Saya mencobanya di / rumah. Saya punya 698035 . Saya harus melihat sekitar 6 angka.
xenoterracide
Ini berfungsi untuk saya - apakah Anda yakin hanya memiliki 6 file di bawah /home? Saya akan 100% yakin Anda tidak.
Cry Havok
4

Solusi berikut menghitung jumlah sebenarnya dari inode yang digunakan mulai dari direktori saat ini:

find . -print0 | xargs -0 -n 1 ls -id | cut -d' ' -f1 | sort -u | wc -l

Untuk mendapatkan jumlah file dari subset yang sama, gunakan:

find . | wc -l

Untuk solusi yang menjelajahi hanya subdirektori, tanpa memperhitungkan file akun di direktori saat ini, Anda dapat merujuk ke jawaban lain.

mouviciel
sumber
1
Ide bagus, memperhitungkan tautan keras. Dengan asumsi GNU menemukan, Anda tidak perlu begitu banyak langkah: find -printf '%i\n' | sort -u | wc -l. Jika Anda ingin portabel, Anda akan perlu find . -exec ls -id {} + | cut ….
Gilles 'SANGAT berhenti menjadi jahat'
2

OS X 10.6 mencekik perintah dalam jawaban yang diterima, karena tidak menentukan jalur untuk find. Alih-alih gunakan:

find . -maxdepth 1 -type d | while read -r dir; do printf "%s:\t" "$dir"; find "$dir" -type f | wc -l; done
abeboparebop
sumber
2

Saya tahu saya terlambat ke pesta, tetapi saya percaya bashsolusi murni ini (atau cangkang lain yang menerima gumpalan bintang ganda) bisa jauh lebih cepat dalam beberapa situasi:

shopt -s globstar    # to enable ** glob in bash
for dir in */; do a=( "$dir"/**/* ); printf "%s\t%s\n" "$dir:" "${#a[*]}"; done

keluaran:

d1/:    302
d2/:    24
d3/:    640
...
jimmij
sumber
1

Cobalah ini:

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

Seharusnya berfungsi dengan baik kecuali nama file menyertakan baris baru.

Dennis Williamson
sumber
terlalu rekursif ... Saya hanya ingin melihat level atas, di mana total semuanya ada di bawahnya. totaled ... ini akhirnya mencetak setiap direktori.
xenoterracide
@xenoterracide: Coba tambahkan -maxdepth 1segera setelah yang pertama find. Jika Anda ingin memasukkan jumlah subdirektori dalam hitungan Anda, hapus bagian -type fakhir (yang seharusnya benar-benar ada ! -type d, sehingga semua file non-direktori akan dimasukkan).
Dennis Williamson
1

Jika Anda telah ncdumenginstal (yang harus dimiliki ketika Anda ingin melakukan pembersihan), cukup ketik cuntuk "Beralih tampilan jumlah item anak". Dan Cuntuk "Urutkan berdasarkan item".

Demi-Lune
sumber
1
haha, ini pasti jawaban paling banyak diterima :)
x-yuri
0

du --inode

Saya tidak yakin mengapa tidak ada orang (termasuk saya) yang menyadari:

du --inodes
--inodes
      list inode usage information instead of block usage

Saya cukup yakin ini memecahkan masalah OP. Saya sudah mulai sering menggunakannya untuk mencari tahu di mana semua sampah di drive saya yang besar (dan menurunkannya ke disk yang lebih tua).

Info lebih lanjut

Jika Anda TIDAK ingin berulang (yang dapat berguna dalam situasi lain), tambahkan

-S, --separate-dirs
Sridhar Sarnobat
sumber