Hitung jumlah total file dalam direktori tertentu dengan ekstensi spesifik

32

Saya ingin menghitung jumlah total file dalam direktori tertentu yang berakhir dengan ekstensi ".mp4".

Saya mendapatkan perintah berikut:

ls -F |grep -v / | wc -l

Itu menghitung semua file dalam direktori tertentu, tetapi saya ingin jumlah file yang berakhir dengan ekstensi .mp4.

Apakah ada perintah Ubuntu untuk itu?

Prakash V Holkar
sumber
2
Jawaban sederhana, benar, langsung adalah @ louis-matthijssen. ls -1penanganan karakter baris baru, dalam hal ini, masuk akal untuk mengurai lsoutput. Yang ditandai salah untuk penggunaan flag -R.
Rmano

Jawaban:

19

Di sini Anda bisa melakukannya dengan cara ini

ls -lR /path/to/dir/*.jpg | wc -l

Ini memberi Anda menghitung

sk1712
sumber
5
Mengapa -R? Mengapa melakukan penuh statketika Anda hanya membutuhkan nama file? Mengapa tidak ls -1 *.jpg| wc -l? (ok, tidak berfungsi jika Anda memiliki nama file dengan baris baru di dalamnya. Dalam hal ini Anda layak mendapatkannya ;-) ...)
Rmano
2
... dan pertanyaannya adalah "menghitung jumlah file dalam direktori". Selain itu, ini akan mendaftar secara rekursif semua konten subdirektori yang namanya berakhiran .jpg , bukan file di subdirektori yang berakhiran .jpg. Apakah Anda pernah mengujinya?
Rmano
1
Pertanyaannya mengatakan "file dalam direktori tertentu", yang menyiratkan bahwa rekursi subdirektori tidak diinginkan.
David Richerby
1
Ini juga gagal jika ada terlalu banyak file dalam direktori (karena *.jpgdiperluas oleh shell, bukan oleh ls) dan jika ada file yang namanya dimulai dengan tanda hubung.
David Richerby
2
@ DavidRicherby Ini melompati nama yang dimulai dengan .. Tapi itu benar-benar berfungsi dengan tanda hubung dalam nama, kecuali kapan /path/to/dirstring kosong atau jalur relatif dimulai dengan tanda hubung. Tapi saya salah sebelum mengatakan lsmengganti karakter dengan ?. Itu terjadi ketika stdout adalah terminal, tetapi di sini outputnya adalah sebuah pipa sehingga lsmengirim semua karakter dari nama file ke wc. Itu membuat jawaban ini salah tanpa tanda -qatau -buntuk mengubah perilaku itu , karena nama file dapat berisi baris baru. Jawaban l0b0 bebas dari masalah ini.
Eliah Kagan
42

Sayangnya masalah jinak ini sulit dipecahkan dengan cara yang mendukung semua nama file dan bersifat portabel. Ini aman (menangani file-file tersembunyi, jalur yang berisi spasi, tanda hubung dan bahkan baris baru) dan kompatibel dengan POSIX :

find /path/to/directory -mindepth 1 -type f -name "*.mp4" -printf x | wc -c

Jika Anda tidak ingin rekursif, cukup tambahkan -maxdepth 1.

Anda tidak harus mengurai lsoutput.

Uji:

$ cd -- "$(mktemp -d)"
$ touch -- -foo.mp4 .bar.mp4 .bat.mp4 'baz.mp4
> ban.mp4'
$ find . -mindepth 1 -type f -name "*.mp4" -exec printf x \; | wc -c
4

Bandingkan dengan jawaban yang diterima :

$ ls -lR ./*.mp4 | wc -l
3

Atau saran lain:

$ find . -name "*.mp4" | wc -l
5
$ ls -1 *.mp4 | wc -l
ls: invalid option -- '.'
Try 'ls --help' for more information.
0
$ find . -name "*.mp4" | wc -c # Answer fixed at a later time
51
$ find . -name "*.mp4" | wc -l
5
$ find . | grep -i ".mp4$" | wc -l
5
$ ls . | grep ".mp4$" | wc -l
3
l0b0
sumber
2
Meskipun jawaban ini benar dan kuat, Anda dapat menggunakannya -printf xsebagai gantinya -exec printf x \;. Yaitu: find /path/to/directory -mindepth 1 -type f -name "*.mp4" -printf x | wc -c Tidak perlu perintah -execeksternal printf, yang jika ada banyak file akan sangat lambat , karena findharus memotong (2) dari salinan dirinya sendiri dan kemudian mengeksekusi (2) /usr/bin/printf . Dengan -exec printf x \;, itu harus dilakukan satu kali untuk setiap file .
Eliah Kagan
-printftidak didukung dalam POSIXfind , itulah sebabnya saya tidak menggunakannya.
l0b0
1
Tidak ada -mindepthdan -maxdepth, yang Anda gunakan.
Eliah Kagan
Poin bagusnya, saya belum memahami itu!
l0b0
BSD findmengandung -mindepthdan -maxdepthtetapi tidak mengandung -printfjadi saya sangat menghargai masuknya keduanya.
Joseph
11

Yang ini menemukan, mengurutkan, dan mendaftar semua file dengan ekstensi agar:

find . -type f | sed 's/.*\.//' | sort | uniq -c
squozen
sumber
Luar biasa! Saya hanya akan menambahkan | sort -rndi akhir dan mungkin -mindepth 1jika hanya dir saat ini.
Pablo A
Dan mungkin pipa ke head -nuntuk mendapatkan puncak n.
Raman
jawaban yang sangat bagus, terima kasih banyak
Dennis Golomazov
5

Saya pikir ini sangat sederhana sebagai perintah berikut.

$ find . -name "*.mp4" | wc -l
8

atau

$ find . | grep -i ".mp4$" | wc -l
8

Saya pikir perintah di atas menghitung jumlah file dan nama direktori *.mp4

jadi saya sarankan Anda menggunakan -type fopsi sebagai findparameter sebagai berikut.

$ find . -name "*.mp4" -type f | wc -l
8

Selain itu, ls -lRbisa digunakan sebagaifind .

Xiaodongjie
sumber
2

Anda bisa menggunakannya ls -1 *.mp4 | wc -l.

Ini akan mencantumkan semua file yang berakhir .mp4, mencetak setiap file pada baris baru ( ls -1 *.mp4), menyalurkan output wcyang akan menghitung jumlah baris baru menggunakan -lbendera.

Louis Matthijssen
sumber
Tidak yakin mengapa ini dibatalkan, ia bekerja
Panther
Karena *.mp4diperluas oleh shell, tidak ls, ini akan gagal jika ada begitu banyak .mp4file dalam direktori yang daftar mereka tidak dapat diteruskan lssebagai argumen.
David Richerby
@Rmana Mengujinya dalam direktori yang berisi file bernama--.mp4
David Richerby
@ DavidRicherby ya, Anda benar. --akan menyelesaikan kasus kedua; yang pertama akan memunculkan pesan kesalahan (Anda perlu banyak file!) dan pertanyaan bagus lainnya di sini. Kasing sudut, tapi perlu diperhatikan, ya.
Rmano
1
@Rmano Tanpa menambahkan -qatau -b, ini tidak mentolerir baris baru dalam nama file. Jika Anda lari ls -1 *.mp4dari terminal Anda tanpa pipa, lslihat stdout -nya adalah terminal dan -qsesuai dengan yang tersirat, pencetakan ?. Tapi perilaku itu hilang ketika output disalurkan. ls -1 *.mp4 | wc -lovercounts jika ada baris baru. ls -1 *.mp4 | catmenunjukkan apa yang wc"dilihat." (Demikian pula, -1tersirat ketika stdout bukan terminal, jadi itu opsional.) ls -1q -- *.mp4 | wc -lHampir berfungsi, tetapi tidak dengan nol .mp4 file.
Eliah Kagan
0

Ini akan memberi Anda daftar file dengan .mp4

ls /path/to/directory | grep ".mp4$"

Ketika dikombinasikan dengan wc -lakan memberi Anda menghitung

ls /path/to/directory | grep ".mp4$" | wc -l

jika Anda ingin mencari untuk menyertakan subdirektori

ls -lR /path/to/directory | grep ".mp4$" | wc -l
Kembali
sumber
tidak memberikan hitungan
Panther
memberikannya kepada saya ketika digunakan denganwc -l
Back.Slash
gunakan ls tanpa piping untuk menangkap dan mempersingkat jawaban Anda. Sudah diposting setidaknya dua kali sekarang.
Panther
@ bodhi.zazen ls /directory/*.mp4menyebabkan shell memperluas glob dan menjalankan sesuatu seperti ls /directory/file1.mp4 /directory/file2.mp4 ...ini akan gagal jika direktori berisi lebih banyak file mp4 daripada yang bisa diteruskan sebagai argumen ls.
David Richerby
@ DavidRicherby - itu bukan perintah ls saya, saya menggunakan find;)
Panther
0

Di bash, satu resor dingin menggunakan array dengan glob:

$ files=( *.mp4  )
$ echo ${#files[@]}
30
Sergiy Kolodyazhnyy
sumber
0
ls | grep --count \.csv$

Ganti (.csv dengan ekstensi yang Anda inginkan)

Penjelasan: Saya pikir skema sederhana adalah mengambil daftar file, dan menghitung ekstensi dengan grep. \.untuk mencocokkan .dan $mencocokkan ekstensi di akhir baris. Ini berfungsi karena ketika output ls disalurkan, satu nama file dikirim per baris, yang dapat Anda verifikasi dengan menjalankan:

ls | cat
Mohsin Raza
sumber
1
Perhatikan bahwa alih-alih grep --count, Anda juga bisa menggunakan grep -c.
Mohsin Raza