Bagaimana saya bisa mendapatkan jumlah file dalam direktori menggunakan baris perintah?

193

Saya memiliki direktori dengan banyak file. Saya tidak melihat lssaklar untuk memberikan hitungan. Apakah ada sihir baris perintah untuk mendapatkan hitungan file?

Blake
sumber
tree . | tailatau tree -a . | tailuntuk memasukkan file / direktori tersembunyi, treebersifat rekursif jika itu yang Anda inginkan.
CodyChan

Jawaban:

239

Menggunakan definisi luas "file"

ls | wc -l

(perhatikan bahwa itu tidak menghitung file tersembunyi dan menganggap bahwa nama file tidak mengandung karakter baris baru).

Untuk memasukkan file tersembunyi (kecuali .dan ..) dan menghindari masalah dengan karakter baris baru, cara kanonik adalah:

find . ! -name . -prune -print | grep -c /

Atau secara rekursif:

find .//. ! -name . -print | grep -c //
James Roth
sumber
23
wcadalah program "jumlah kata". The -lberalih menyebabkannya untuk menghitung garis. Dalam hal ini, ia menghitung garis dalam output dari ls. Ini selalu cara saya diajarkan untuk mendapatkan jumlah file untuk direktori yang diberikan juga.
Sandy
20
tolong tambahkan catatan yang lsberfungsi ls -1jika outputnya berupa pipa.
lesmana
6
itu tidak mendapatkan semuanya dalam direktori - Anda telah melewatkan file dot, dan mengumpulkan beberapa baris tambahan juga. Direktori kosong masih akan mengembalikan 1 baris. Dan jika Anda menelepon ls -la, Anda akan mendapatkan tiga baris dalam direktori. Anda ingin ls -lA | wc -lmelewati .dan ..entri. Anda akan tetap off-by-one.
1
Direktori kosong mengembalikan 0 untuk saya
James Roth
2
Pendekatan yang dikoreksi, yang tidak akan menggandakan file dengan baris baru dalam namanya, akan menjadi ini: ls -q | wc -l- meskipun perhatikan bahwa file tersembunyi masih tidak akan dihitung oleh pendekatan ini, dan direktori akan dihitung.
godlygeek
31

Untuk definisi file yang sempit:

 find . -maxdepth 1 -type f | wc -l
Maciej Piechotka
sumber
Dan Anda tentu saja dapat menghilangkan -maxdepth 1untuk menghitung file secara rekursif (atau menyesuaikannya untuk kedalaman pencarian maks yang diinginkan).
user7089
1
Jika Anda memiliki file yang namanya berisi baris baru, pendekatan ini akan salah menghitungnya dua kali.
godlygeek
7
Pendekatan yang diperbaiki, yang tidak akan menggandakan file dengan baris baru dalam nama, akan menjadi ini:find -maxdepth 1 -type f -printf "\n" | wc -l
godlygeek
+1 Mengizinkan file tersembunyi dan mengabaikan direktori
Michael Durrant
14
ls -1 | wc -l

...

$ ls --help | grep -- '  -1'
    -1                         list one file per line

...

$ wc --help | grep -- '  -l'
    -l, --lines            print the newline counts

PS: Catatan ls - <nomor-one> | wc - <letter-l>

nicomen
sumber
10
Sebagian besar versi lsdilakukan -1secara otomatis ketika output ke pipa.
Dennis Williamson
3
@ Dennis itu menarik saya tidak tahu bahwa aplikasi bisa mengatakan outputnya akan ke pipa.
xenoterracide
1
Saya telah mengedit versi ini karena lebih eksplisit. Padahal, ya ls memang menggunakan -1 jika disalurkan (coba saja: ls | cat), saya menemukan sintaks -1 lebih eksplisit.
gabe.
3
@xenoterracide: In Bash:[[ -p /dev/stdin ]] && echo "stdin is from a pipe"
Dennis Williamson
2
Dalam pengujian saya, secara signifikan lebih cepat juga memberikan opsi -f untuk menghindari ls menyortir nama file. Sayangnya Anda masih mendapatkan jawaban yang salah jika nama file Anda mengandung baris baru.
Samuel Edwin Ward
10

Mungkin jawaban yang paling lengkap menggunakan ls/ wcpair adalah

ls -Aq | wc -l

jika Anda ingin menghitung file dot, dan

ls -q | wc -l

jika tidak.

  • -Aadalah untuk menghitung file dot, tetapi hilangkan .dan ...
  • -qmembuat lsganti karakter nongraphic, khususnya karakter baris baru, dengan ?, membuat output 1 baris untuk setiap file

Untuk mendapatkan output satu jalur dari lsdalam terminal (yaitu tanpa memasukkannya ke dalam wc), -1opsi harus ditambahkan.

(perilaku lsdiuji dengan coreutils 8.23)

Frax
sumber
2
Seperti yang Anda katakan, -1tidak diperlukan. Mengenai "ia menangani baris baru dalam nama file dengan masuk akal dengan output konsol" , ini karena -qsakelar (yang harus Anda gunakan alih-alih -bkarena portabel) yang "memaksa setiap instance karakter nama file yang tidak dapat dicetak dan karakter <tab> yang akan ditulis sebagai karakter <question-mark> ('?'). Implementasi dapat menyediakan opsi ini secara default jika outputnya ke perangkat terminal. " Jadi mis. ls -Aq | wc -lUntuk menghitung semua file / direktori atau ls -qp | grep -c /untuk menghitung hanya direktori yang tidak tersembunyi, dll ...
don_crissti
Terima kasih atas masukan Anda. Diubah -bmenjadi -q.
Frax
7

Jika Anda tahu direktori saat ini mengandung setidaknya satu file yang tidak disembunyikan:

set -- *; echo "$#"

Ini jelas dapat digeneralisasikan untuk semua bola.

Dalam sebuah skrip, ini memiliki efek samping yang kadang-kadang tidak menguntungkan yaitu menimpa parameter posisi. Anda dapat mengatasinya dengan menggunakan subkulit atau dengan fungsi (versi Bourne / POSIX) seperti:

count_words () {
  eval 'shift; '"$1"'=$#'
}
count_words number_of_files *
echo "There are $number_of_files non-dot files in the current directory"

Solusi alternatif adalah $(ls -d -- * | wc -l). Jika glob adalah *, perintah dapat disingkat menjadi $(ls | wc -l). Mem-parsing output lsselalu membuat saya gelisah, tapi di sini seharusnya berfungsi selama nama file Anda tidak mengandung baris baru, atau Anda lslolos darinya. Dan $(ls -d -- * 2>/dev/null | wc -l)memiliki keuntungan menangani kasus gumpalan yang tidak cocok dengan anggun (yaitu, mengembalikan 0 dalam kasus itu, sedangkan set *metode ini membutuhkan pengujian fiddly jika gumpalan mungkin kosong).

Jika nama file dapat berisi karakter baris baru, alternatifnya adalah menggunakan $(ls -d ./* | grep -c /).

Salah satu solusi yang mengandalkan meneruskan ekspansi bola dunia lsmungkin gagal dengan daftar argumen kesalahan terlalu lama jika ada banyak file yang cocok.

Gilles
sumber
1
Apakah Anda benar-benar ingin membuat 13.923 parameter posisi? Dan Anda harus membuat variabel lokal Anda localatau menghilangkannya: eval $1=$#atau hanya menggunakan echo $#dan melakukan number_of_files=$(count_words *).
Dennis Williamson
1
@ Dennis: bagian dari maksudnya adalah untuk menghindari forking. Saya kira itu bukan masalah abad ke-21. Ok, saya akui saya tidak peduli lagi dengan kerang non-POSIX, jadi saya bisa menghindari variabel sementara.
Gilles
Mengapa Anda mengurangi satu dari $#(Anda belum melakukan itu sebelum edit)?
Dennis Williamson
@ Dennis: Saya masih menghindari garpu (well, itu membuat perbedaan pada mesin dengan CPU lambat seperti router) dan melewati nama variabel sebagai $1. Jadi yang ingin saya hitung adalah jumlah parameter yang bukan parameter pertama. (Saya tidak bisa menggunakan shiftkarena saya harus menjaga nama variabel tetap ada.) (Umm, sekarang jika Anda bertanya tentang baris pertama ...)
Gilles
@ Dennis: kalau dipikir-pikir, saya bisa menggunakan shiftjika saya mengatur waktu dengan benar.
Gilles
7

Saya menemukan du --inodesbermanfaat, tetapi saya tidak yakin versi mana yang dudibutuhkan. Itu harus jauh lebih cepat daripada pendekatan alternatif menggunakan finddan wc.

Di Ubuntu 17.10, yang berikut ini berfungsi:

du --inodes      # all files and subdirectories
du --inodes -s   # summary
du --inodes -d 2 # depth 2 at most

Gabungkan dengan | sort -nruntuk mengurutkan menurun berdasarkan jumlah inode yang mengandung.

krlmlr
sumber
5

Saat menggunakan pasangan ls / wc jika kita menambahkan -U akan jauh lebih cepat (jangan urutkan).

ls -AqU | wc -l
Jbnair
sumber
1
-Ukhusus untuk GNU.
Stéphane Chazelas
4

Setelah menginstal perintah tree, ketikkan:

tree

Jika Anda ingin file tersembunyi juga:

tree -a

Jika Anda menggunakan Linux Debian / Mint / Ubuntu, ketikkan perintah berikut untuk menginstal perintah pohon:

sudo apt-get install tree

Opsi -L digunakan untuk menentukan level tampilan maksimum pohon direktori. Perintah tree tidak hanya menghitung jumlah file, tetapi juga jumlah direktori, mengingat sebanyak level pohon direktori yang Anda inginkan.

lev
sumber
Ketika saya mengetik pohon, saya mendapatkan semacam keluaran pohon ke layar direktori tempat saya berada, tetapi saya tidak bisa melihat di mana jumlah file ditampilkan.
charlesdarwin
2
find -maxdepth 1 -type f -printf . | wc -c
  • -maxdepth 1akan membuatnya non-rekursif, findbersifat rekursif secara default
  • -type f hanya akan menyertakan file
  • -printf .adalah sentuhan imut. itu mencetak titik untuk setiap file, bukan nama file, dan sekarang ini dapat menangani nama file apa pun dan juga menyimpan data; kita hanya harus menghitung titik-titik :)
  • | wc -c menghitung karakter
aude
sumber
1

Tidak ada pipa, tidak ada salinan string, tidak ada garpu, hanya bash polos satu liner

$ fcount() { local f i=0; for f in *; do let i++; done; echo $i; }; fcount
DaboD
sumber
1
Memberikan nilai 1 jika tidak ada file dalam direktori. Tidak menghitung file, menghitung file, dan direktori.
steve
1

Berikut teknik lain yang ditulis oleh Gilles :

word_count () { local c=("$@"); echo "${#c[@]}"; }
file_count=$(word_count *)

yang menciptakan array dengan 13.923 elemen (jika ada berapa banyak file).

Dennis Williamson
sumber
Apa gunanya carray itu? word_count() { echo "$#"; }akan cukup. Inti dari solusi @Gilles adalah untuk menyimpan hitungan dalam variabel yang dikembalikan untuk menghindari keharusan menggunakan substitusi perintah (yang melibatkan garpu dan pipa dalam cangkang selain ksh93).
Stéphane Chazelas
1
find . -type f -maxdepth 1 |  wc -l 

Ini hanya dapat menampilkan file dalam direktori saat ini.

pappu
sumber
find . -type fakan menemukan file di direktori saat ini, dan juga, secara rekursif, di sub-direktori.
Dhag
0

Coba ini saya harap jawaban ini akan membantu Anda

echo $((`ls -l | wc -l` -1 ))
Harimau
sumber
0

Anda dapat memeriksa dengan:

ls -l | grep -v ^l | wc -l
AMIC MING
sumber
0

Meningkatkan beberapa jawaban yang diberikan sebelumnya tetapi kali ini dilakukan secara eksplisit.

$ tree -L 1 | tail -n 1 | cut -d " " -f 3

Layak untuk memperhatikan penggunaan beberapa perintah yang dicintai seperti taildan cut. Juga, perhatikan bahwa pohon tidak tersedia secara default. Perintah di atas pertama-tama menangkap informasi tentang direktori pada level 1, lalu dapatkan baris terakhir di tail -n 1mana tujuan kita, dan berakhir dengan cutmengambil kata ketiga.

Misalnya, mencari di /:

/ $ tree -L 1
.
├── 1
├── bin -> usr/bin
├── boot
├── dev
├── etc
├── home
├── lib -> usr/lib
├── lib64 -> usr/lib64
├── lost+found
├── media
├── mnt
├── opt
├── proc
├── root
├── run
├── sbin -> usr/sbin
├── srv
├── sys
├── tmp
├── usr
└── var

20 directories, 1 file
/ $ tree -L 1 | tail -n 1
20 directories, 1 file
/ $ tree -L 1 | tail -n 1 | cut -d " " -f 3
1

Lalu, bagaimana dengan menanyakan jumlah direktori?

Jonaprieto
sumber
0

Di Linux, untuk membuat perintah sangat kuat dan menangani file yang mungkin memiliki baris baru dalam namanya, gunakan ini:

find -maxdepth 1 -type f -print0 | tr -cd '\0' | wc -c

Ini menyelamatkan kita dari cobaanls keluaran parsing .


Terkait:

codeforester
sumber
-2

Gunakan treeperintah, cukup:

tree
pengguna115186
sumber