Temukan direktori yang berisi sejumlah file tertentu

13

Berharap saya bisa melakukan ini dengan findperintah tetapi saya tidak dapat melihat tes dalam manual untuk melakukan apa yang saya inginkan. Saya ingin dapat menemukan direktori di direktori kerja yang berisi kurang dari, lebih dari atau persis jumlah yang saya tentukan.

find . -filecount +10 # any directory with more than 10 entries
find . -filecount 20 # any directory with exactly 20 entries

Namun sayang tidak ada opsi seperti itu.

Paul Ruane
sumber
coba sesuatu seperti "ls -al | wc -l | grep"
Vanadis

Jawaban:

16

Anda dapat mencoba ini, untuk mendapatkan nama sub direktori dan jumlah file / direktori yang dikandungnya:

find . -maxdepth 1 -type d -exec bash -c "echo -ne '{} '; ls '{}' | wc -l" \;

Jika Anda ingin melakukan hal yang sama untuk semua sub direktori (pencarian rekursif) gunakan ini sebagai gantinya:

find . -type d -exec bash -c "echo -ne '{} '; ls '{}' | wc -l" \;

Untuk memilih direktori yang memiliki tepat 10 file:

find . -maxdepth 1 -type d -exec bash -c "echo -ne '{} '; ls '{}' | wc -l" \; | 
  awk '$NF==10'

10 atau lebih:

find . -maxdepth 1 -type d -exec bash -c "echo -ne '{} '; ls '{}' | wc -l" \; | 
 awk '$NF>=10'

10 atau kurang:

find . -maxdepth 1 -type d -exec bash -c "echo -ne '{} '; ls '{}' | wc -l" \; | 
 awk '$NF<=10'

Jika Anda ingin menyimpan hanya nama direktori (misalnya Anda ingin mengirimnya ke proses hilir lainnya seperti yang disarankan @evilsoup) Anda dapat menggunakan ini:

find . -maxdepth 1 -type d -exec bash -c "echo -ne '{}\t'; ls '{}' | wc -l" \; | 
 awk -F"\t" '$NF<=10{print $1}'
terdon
sumber
1
Saya pikir mungkin berguna untuk memasukkan perintah awk untuk memotong jumlah file (yaitu kolom spasi-dibatasi terakhir), jika penanya ingin menyalurkan output ke sesuatu yang lain.
evilsoup
1
@ evilsoup ide bagus, sudah selesai.
terdon
Untuk mendukung spasi putih dan karakter khusus dalam nama direktori; coba balikkan penggunaan tanda kutip tunggal dan ganda sebagai berikut:find . -type d -exec bash -c 'echo -ne "{} "; ls "{}" | wc -l' \; | awk '$NF<=10'
Håvard Geithus
3

Untuk daftar subdirektori langsung yang berisi file persis $NUM .

find -maxdepth 2 -mindepth 2 -type f -printf '%h\0' | awk -v num="$NUM" 'BEGIN{RS="\0"} {array[$0]++} END{for (line in array) if (array[line]==num) printf "%s\n", line}'

Untuk daftar subdirektori langsung yang berisi lebih dari $NUMfile.

find -maxdepth 2 -mindepth 2 -type f -printf '%h\0' | awk -v num="$NUM" 'BEGIN{RS="\0"} {array[$0]++} END{for (line in array) if (array[line]>num) printf "%s\n", line}'

Untuk daftar subdirektori langsung yang berisi kurang dari $NUMfile.

find -maxdepth 2 -mindepth 2 -type f -printf '%h\0' | awk -v num="$NUM" 'BEGIN{RS="\0"} {array[$0]++} END{for (line in array) if (array[line]<num) printf "%s\n", line}'

Item dihentikan oleh karakter nol \0, sehingga nama file yang berisi baris baru atau jenis ruang putih lainnya akan ditafsirkan dengan benar. The %hmencetak masing-masing file dirname. awkkemudian menggunakan array untuk menghitung berapa kali bertemu setiap direktori, mencetaknya jika kondisi terpenuhi.

Harap dicatat bahwa tidak ada perintah yang disebutkan di atas yang akan menampilkan direktori yang berisi nol file. Juga perhatikan bahwa berdasarkan file saya mengacu pada file biasa, bukan tautan, direktori, soket, blok, pipa bernama, dan sebagainya.

Saya sudah mencoba melakukan ini sesederhana mungkin. Jika Anda ingin menemukan subdirektori rekursif atau file-file di dalamnya, diperlukan perintah yang dimodifikasi. Ada terlalu banyak kemungkinan untuk mendaftar semuanya.

Enam
sumber
2

Coba ini:

[`temukan. | wc -l` -eq 10] && echo "Ditemukan"

[`temukan. | wc -l` -gt 10] && echo "Ditemukan"

[`temukan. | wc -l` -lt 10] && echo "Ditemukan"

Dalam contoh ini Anda dapat memeriksa apakah direktori CURRENT mengandung tepat 10, lebih dari 10 dan kurang dari 10 file / direktori. Jika Anda perlu memeriksa banyak direktori, cukup gunakan loop.

September
sumber
Solusi Anda juga menghitung direktori saat ini ( .), Anda mungkin ingin memodifikasi sesuai.
terdon
Saya menyukai dorongan jawaban ini (karena saya pelahap untuk melakukan hal-hal di shell), tetapi Anda akan lebih baik menggunakan wc -l < <(printf %s\\n ./*)atau printf %s\\n ./* | wc -ldi dalam tes, untuk menghindari findpanggilan yang tidak perlu . Ini juga akan menghindari masalah yang dicatat @terdon, termasuk .dalam hasilnya. Namun, itu juga akan mengalami masalah mengabaikan file yang dimulai dengan .; Saya akan menyelesaikan ini dengan shopt -s dotglob(untuk membuat gumpalan file pertandingan dimulai dengan ., tetapi tidak .atau ..).
evilsoup
@terdon Itu tidak penting. Ini bukan solusi final, hanya contoh, ide. Anda dapat -1, atau mengubah 10 hingga 11 dalam versi final.
september
Saya tahu, dan idenya bagus itu sebabnya saya membuat saran.
terdon
@ terdon. Terima kasih. Mungkin ada banyak persyaratan yang berbeda, seperti: Menghitung hanya file tetapi bukan direktori, atau tautan, atau tautan keras. Hitung atau tidak file dalam subdirektori. Hitung file yang disembunyikan (seperti .bashrc) ... ... sehingga ekspresi Anda bisa terlalu lama. :)
september