Dapatkan daftar nama direktori dengan find

35

Saya tahu saya bisa melakukan ini untuk mendapatkan daftar nama direktori:

find . -type d -maxdepth 1 

Outputnya terlihat seperti ini:

.
./foo
./bar

Saya lebih suka daftar tanpa ./. Apakah ada cara untuk mendapatkan find untuk menghasilkan hanya nama-nama mentah?

Saya mencoba mengirim daftar ke stat untuk memformatnya tetapi itu hanya memberi saya hasil yang sama:

find . -type d -maxdepth 1 -print0 | xargs -0 stat -f '%N'
joachim
sumber
jadi Anda ingin foo bar ...semua dalam satu baris tanpa ./di depan?
Levon
Apakah ini murni karena alasan kosmetik / estetika atau Anda mencoba melakukan sesuatu dengan output?
jw013

Jawaban:

42

Dengan GNU findAnda dapat menggunakan -printfopsi:

find . -maxdepth 1 -type d -printf '%f\n'

Seperti dicatat oleh Paweł dalam komentar, jika Anda tidak ingin direktori saat ini terdaftar tambahkan -mindepth 1, misalnya:

find . -mindepth 1 -maxdepth 1 -type d -printf '%f\n'
Thor
sumber
Saya tidak dapat menemukan -printfopsi apa pun dalam spesifikasi POSIX terbaru dan saya ingin tahu seberapa portabelnya ...
rahmu
@rahmu: Ini diuji dengan GNU find. Tidak ada printfopsi yang disebutkan oleh POSIX dan sepertinya tidak didukung oleh beberapa findversi lainnya . GNU find dapat diinstal di sebagian besar tempat, jadi dalam arti itu portabel.
Thor
1
tambahkan juga -mindepth 1jika Anda ingin menyingkirkan.
Paweł Prażak
18

Memperbarui:

Alternatif yang lebih pendek:

 find . -maxdepth 1 -type d | cut -c 3-

Akan memberi Anda nama, satu per baris, tanpa garis miring

Levon
sumber
4
@ downvoter .. downvote tanpa penjelasan tidak membantu siapa pun (OP, SO atau saya). Ini adalah solusi fungsional untuk pertanyaan OP. Saya senang memperbaiki kesalahan jika menunjukkan atau meningkatkan jawaban, tetapi itu membutuhkan umpan balik yang membangun daripada hanya "klik" anonim.
Levon
1
Saya orang yang downvoted ketika jawaban Anda termasuk penguraian ls. Pada saat yang sama saya telah memposting tautan mengapa ini adalah ide yang buruk pada jawaban lain yang dihapus sejak saat itu. Pada saat itu hanya ada 2 jawaban dan alasannya tampak jelas. Saya senang Anda menunjukkan ambiguitas, dan inilah penjelasan saya. Sebagai catatan, saya mengubah downvote saya dalam upvote karena saya setuju dengan jawaban Anda saat ini.
rahmu
@rahmu Memberi penjelasan untuk downvote Anda di pertanyaan lain tidak membantu saya (dan hanya jelas bagi Anda). Selain itu, walaupun ini adalah solusi yang lebih baik, solusi yang saya posting sebelumnya bekerja dengan baik (ya, saya kenal dengan tautan "jangan gunakan ls" Anda - tetapi tidak berlaku secara membabi buta dalam semua kasus). Jika Anda memiliki contoh balasan mengapa solusi awal saya tidak berhasil, saya ingin mengetahuinya (sehingga saya benar-benar dapat belajar sesuatu dari ini), jika tidak, Anda hanya memposting tautan dan tidak menawarkan sesuatu yang konstruktif.
Levon
Pertimbangkan ada \ndalam nama direktori yang tidak dapat Anda gunakan untuk mengambilnya (yang adalah apa yang Anda lakukan ketika saya menurunkan Anda). Ada beberapa kasus di mana lstidak berperilaku berbahaya dan hampir selalu lebih aman untuk menggunakan cara lain.
rahmu
9

Menggunakan GNU find, Anda bisa menggunakan -mindepth untuk mencegah ditemukannya cocok dengan direktori saat ini:

find . -type d -maxdepth 1 -mindepth 1

Karena Anda tidak melakukan ini secara rekursif, Anda dapat menggunakan bash glob:

echo */

Menambahkan trailing / ke glob akan menyebabkan hanya direktori yang cocok.

jordanm
sumber
1
*/meleset file dot dan termasuk symlink. Ini mungkin atau mungkin tidak menjadi masalah.
Gilles 'SANGAT berhenti menjadi jahat'
@Gilles - Ini akan selalu kehilangan symlink, tetapi dotfiles tergantung pada apakah dotglob diatur atau tidak.
jordanm
6

Mari sedhapus kedua karakter itu:

find . -maxdepth 1 -type d | sed -e 's/^\.\///'
Birei
sumber
6

Saya lebih suka menggunakan:

 find ./ -type d -maxdepth 1 -exec basename {} \;
pengguna1293137
sumber
2

Saya biasanya menggunakan:

find * -type d

Tetapi saya tidak tahu apakah itu cara yang tepat untuk melakukan apa yang Anda inginkan.

Francesco Turco
sumber
1
Jika Anda akan membiarkan shell memperluas semua nama file, mengapa harus menggunakan find?
jordanm
@jordanm Untuk hanya memilih direktori. echo */akan melakukan hal yang sama, lebih atau kurang (itu meleset file dot dan termasuk symlink), tetapi kemudian joachim akan bertanya bagaimana menghapus final /.
Gilles 'SANGAT berhenti menjadi jahat'
0

Dalam AIX apakah parameter 'maxdepth' tidak berfungsi.

Secara umum ini bekerja untuk saya:

find ./ -type d | cut -d"/" -f2 | sort -u

pengguna1656294
sumber
0

Apa yang Anda cari disebut basename, mengabaikan struktur direktori unix

Contoh di bawah ini:

find /any/path/you/want -maxdepth 1 -type d -exec basename {} \;

itu akan mengecualikan untuk output bahkan path dir, menghapus keharusan untuk cd sebelum menjalankan perintah


Beberapa info tambahan:

Saya akan meneruskan -execsebagai argumen untuk mencari |(pipa) perintah lain untuk output (menghindari perintah kedua pergi ke setiap baris output, setelah mengatakan bahwa, tergantung pada output itu dapat meningkatkan kinerja untuk skrip)

CATATAN: findopsi tidak bersifat posisional (-maxdepth memengaruhi tes yang ditentukan sebelum serta yang ditentukan setelahnya).

gonzalesraul
sumber