temukan semua subdirektori akhir di pohon

11

diberikan struktur berikut:

oz123@debian:~/ $ tree .
.
├── a
│   ├── a1
│   ├── a2
│   └── a3
├── a1
│   ├── a11
│   ├── a12
│   └── a31
├── b
│   └── b1
│       ├── b11
│       │   └── b21
│       │       └── b31
│       ├── b12
│       └── b3
└── c

16 directories, 0 files

Bagaimana cara menemukan semua node akhir?

Saya menemukan solusi berikut yang tampaknya baik, tetapi saya harus membuktikan bahwa tidak ada test case yang akan gagal.

Halaman bantuan -linksnegara:

Anda juga dapat mencari file yang memiliki jumlah tautan tertentu, dengan '-links'. Direktori biasanya memiliki setidaknya dua tautan keras; mereka. entri adalah yang kedua. Jika mereka memiliki subdirektori, masing-masing dari mereka juga memiliki tautan keras yang disebut .. ke direktori induknya. . dan .. entri direktori biasanya tidak dicari kecuali disebutkan pada baris perintah find.

solusi yang mungkin:

oz123@debian:~/ $ find .  -type d  -links 2
./a/a2
./a/a3
./a/a1
./c
./a1/a31
./a1/a11
./a1/a12
./b/b1/b12
./b/b1/b3
./b/b1/b11/b21/b31
  • Adakah yang bisa memberikan solusi yang lebih baik (tanpa menggunakan pipa dan sed, ini telah menjadi pemain ...)
  • Apakah ini akan berfungsi pada sistem file apa saja?
Oz123
sumber
3
Anda tidak akan menemukan lebih banyak pemain daripada -links 2triknya. Itu tidak akan berhasil btrfs.
Stéphane Chazelas

Jawaban:

3

Sebagai tambahan untuk solusi Anda sendiri -links, saya hanya ingin menambahkan bahwa itu tidak akan berfungsi pada sistem file yang tidak mengikuti konvensi direktori-link Unix. Dari man findpada opsi -noleafini setidaknya CD-ROM, sistem file MS-DOS dan titik pemasangan volume AFS.

Untuk referensi, pertanyaan ini sudah dibahas dengan berbagai solusi yang memang lebih lambat dan biasanya menggunakan perpipaan ke sed / awk dan serupa.

Miroslav Koškár
sumber
3

Ada opsi yang sedikit lebih jelas -empty:

find . -type d -empty

upd. Oke, Anda benar cara ini tidak akan berfungsi dengan file dalam dir.

Jadi di sini ini adalah sistem file tetap versi undependable:

find dtest/ -type d -exec sh -c "if [ \$(find {} -maxdepth 1 -type d | wc -l) -eq 1 ]; then echo {} ; fi" \;
buru-buru
sumber
2
Jika saya mengerti pertanyaannya, direktori akhir mungkin berisi file. Ini tidak akan mencetak direktori tersebut karena tidak akan "kosong" ...
Stefan
@rush, subdir dapat kosong atau tidak
Oz123
@ Oz123 tolong periksa pembaruan saya, itu harus cukup cepat, tetapi sedikit lebih lambat dibandingkan dengan cara Anda.
buru
@rush, terima kasih, tapi aku benar-benar harus menghindari pipa, mereka bisa membuat segalanya lebih lambat.
Oz123
1

find . -type d -links 2bekerja pada sebagian besar sistem file, tetapi tidak semua. Saya tidak berpikir ada cara untuk mengetahui selain mengetahui tipe sistem file mana yang memiliki properti yang mengandung direktori untuk tautannya sendiri. GNU find mendeteksi ini secara dinamis (jika ia mencetak sesuatu tentang "Secara otomatis mengaktifkan opsi find -noleaf", Anda tahu sistem file Anda tidak memiliki properti ini). Jenis sistem file yang paling umum adalah ok, tetapi tidak FAT atau btrfs.

Jika Anda ingin memastikan, Anda harus menguji setiap direktori. Salah satu cara untuk melakukan ini adalah memohon findlagi untuk setiap subdirektori.

find . -type d ! -exec sh -c '
   find "$1/." ! -name . -type d -prune | grep -q "^"' sh {} \; -print

(dengan GNU find, Anda dapat menggantinya -prunedengan -print -quitmembuatnya sedikit lebih efisien).

Cara lain adalah dengan pasca proses output find. Dengan find -depth, direktori daun adalah direktori yang tidak mengikuti subdirektori itu sendiri.

find . -depth -type d -print0 |
awk -v RS='\0' '
    substr(previous, 1, length($0) + 1) != $0 "/"
    { previous = $0 }
'
Gilles 'SANGAT berhenti menjadi jahat'
sumber
0

Coba solusi berikut (harus kompatibel dengan Linux, Unix dan OS X):

find . -type d -execdir sh -c 'test -z "$(find "{}" -mindepth 1 -type d)" && echo $PWD/{}' ';'

Ini pendekatan yang mirip dengan solusi tergesa - gesa , tetapi tanpa pipa.

kenorb
sumber