Jawaban:
Berikut adalah pendekatan yang sama sekali berbeda berdasarkan pada GNU finddan uniq. Ini jauh lebih cepat dan lebih ramah CPU daripada jawaban berdasarkan mengeksekusi perintah shell yang menghitung file untuk setiap direktori yang ditemukan.
find . -type f -printf '%h\n' | sort | uniq -d
The findperintah mencetak direktori dari semua file dalam hirarki dan uniqhanya menampilkan direktori yang muncul setidaknya dua kali.
-printf '%h\0' | sort -z | uniq -zd | xargs -r0 ...
find . -type d \
-exec sh -c 'c=0; for n in "$1"/*; do [ -f "$n" ] && [ ! -h "$n" ] && c=$(( c + 1 )); done; [ "$c" -ge 2 ]' sh {} ';' \
-print
Ini akan menemukan semua nama di atau di bawah direktori saat ini dan kemudian menyaring semua nama yang bukan nama direktori.
Nama direktori yang tersisa akan diberikan ke skrip pendek ini:
c=0
for n in "$1"/*; do
[ -f "$n" ] && [ ! -h "$n" ] && c=$(( c + 1 ))
done
[ "$c" -ge 2 ]
Script ini akan menghitung jumlah file biasa (melewatkan tautan simbolik) di direktori yang diberikan sebagai argumen baris perintah pertama (dari find). Perintah terakhir dalam skrip adalah tes untuk melihat apakah hitungannya 2 atau lebih besar. Hasil tes ini adalah nilai balik (status keluar) dari skrip.
Jika tes berhasil, -printakan menyebabkan finduntuk mencetak jalur ke direktori.
Untuk juga mempertimbangkan file tersembunyi (file yang namanya dimulai dengan titik), ubah sh -cskrip agar tidak mengatakan
for n in "$1"/*; do
untuk
for n in "$1"/* "$1"/.*; do
Pengujian:
$ tree
.
`-- test
|-- a
|-- dir1
| |-- a
| |-- b
| `-- c
`-- dir2
|-- dira
|-- dirb
| |-- file-1
| `-- file-2
`-- dirc
6 directories, 6 files
$ find . -type d -exec sh -c 'c=0; for n in "$1"/*; do [ -f "$n" ] && [ ! -h "$n" ] && c=$(( c + 1 )); done; [ "$c" -ge 2 ]' sh {} ';' -print
./test/dir1
./test/dir2/dirb
[ "" -ge 2 ]ini adalah tes yang valid.
dash, bash --posixdan testsemua menampilkan pesan kesalahan dan keluar dengan 2 (yaitu "Terjadi kesalahan")
kshberjalan seperti mas sh. Akan segera diubah. Terima kasih telah menyodok saya! :-)
[ -f ... ]tautan simbolik dereferensi. Anda harus menambahkan tes untuk menghilangkannya karena pertanyaan menentukan bahwa hanya file biasa yang harus dihitung.
Dengan bantuan jawaban Gilles pada SU dan kebalikannya dan beberapa modifikasi, inilah yang Anda butuhkan.
find . -type d -exec sh -c 'set -- "$1"/*;X=0;
for args; do [ -f "$args" ] && X=$((X+1)) ;done; [ "$X" -gt 1 ] ' _ {} \; -print
Pohon direktori.
.
├── test
│ ├── dir1
│ │ ├── a
│ │ ├── b
│ │ └── c
│ ├── dir2
│ │ ├── dira
│ │ │ └── a file\012with\012multiple\012line
│ │ ├── dirb
│ │ │ ├── file-1
│ │ │ └── file-2
│ │ └── dirc
│ ├── diraa
│ ├── dirbb
│ ├── dircc
│ └── x
│ └── x1
│ └── x2
└── test2
├── dir3
└── dir4
Hasil:
./test
./test/dir1
./test/dir2/dirb
testdan dir2direktori dalam pengujian saya (lihat jawaban saya).
test/x1dan test/x2sebagai file juga ... $1dan $2akan menjadi direktori untuk test, dan direktori akan dilewatkan.
Lain find+ wcpendekatan:
find path/currdir -maxdepth 1 -type d ! -empty ! -path "path/currdir" \
-exec sh -c 'count=$(find "$1" -maxdepth 1 -type f | wc -l); [ $count -ge 2 ]' _ {} \; -print
path/currdir - path ke direktori Anda saat ini
-maxdepth 1- pertimbangkan hanya subfolder anak langsung
! -empty - abaikan subfolder kosong
! -path "path/currdir" - abaikan jalur direktori saat ini
count=$(find "$1" -maxdepth 1 -type f | wc -l)- countditugaskan dengan jumlah file untuk setiap subfolder yang ditemukan
[ $count -ge 2 ] ... -print - cetak nama / jalur subfolder yang berisi 2 atau lebih file biasa
find. Dalam hal ini, karena GNUfindakan memotong-motong nama direktori yang memiliki karakter yang tidak dapat dicetak di lokal saat ini (seperti "ä" di C locale). Lihat juga unix.stackexchange.com/questions/321697/…