user4556274 telah menjawab itu sebabnya . Jawaban saya hanya berfungsi untuk memberikan informasi tambahan tentang cara menghitung file dengan benar.
Dalam komunitas Unix, konsensus umum adalah bahwa mengurai output ls
adalah ide yang sangat sangat buruk , karena nama file dapat berisi karakter kontrol atau karakter tersembunyi. Sebagai contoh, karena karakter baris baru dalam nama file, kami telah ls | wc -l
memberi tahu kami ada 5 baris dalam output ls
(yang memang ada), tetapi dalam kenyataannya hanya ada 4 file dalam direktori.
$> touch FILE$'\n'NAME
$> ls
file1.txt file2.txt file3.txt FILE?NAME
$> ls | wc -l
5
Metode # 1: temukan utilitas
The find
perintah, yang biasanya digunakan untuk bekerja di sekitar parsing nama file, dapat membantu kita di sini dengan mencetak nomor inode . Baik itu direktori atau file, itu hanya memiliki satu nomor inode unik. Dengan demikian, menggunakan -printf "%i\n"
dan mengecualikan .
melalui -not -name "."
kami dapat memiliki jumlah file yang akurat. (Perhatikan penggunaan -maxdepth 1
untuk mencegah turun secara rekursif ke dalam subdirektori)
$> find -maxdepth 1 -not -name "." -print
./file2.txt
./file1.txt
./FILE?NAME
./file3.txt
$> find -maxdepth 1 -not -name "." -printf "%i\n" | wc -l
4
Metode # 2: globstar
Cara sederhana, cepat, dan sebagian besar portabel:
$ set -- *
$ echo $#
228
set
perintah digunakan untuk mengatur parameter posisi shell ( $<INTEGER>
variabel, seperti pada echo $1
). Ini sering digunakan untuk mengatasi /bin/sh
keterbatasan array yang kurang. Versi yang melakukan pemeriksaan tambahan dapat ditemukan dalam jawaban Gille di Unix & Linux.
Dalam shell yang mendukung array, seperti bash
, kita dapat menggunakan
items=( dir/* )
echo ${#items[@]}
seperti yang diusulkan oleh steeldriver dalam komentar .
Trik serupa dengan find
metode yang digunakan wc
dan globstar dapat digunakan stat
untuk menghitung nomor inode per baris:
$> LC_ALL=C stat ./* --printf "%i\n" | wc -l
4
Pendekatan alternatif adalah dengan menggunakan wildcard di for
loop. (Catatan, tes ini menggunakan direktori yang berbeda untuk menguji apakah pendekatan ini turun ke subdirektori, yang tidak - 16 adalah jumlah item yang diverifikasi di saya ~/bin
)
$> count=0; for item in ~/bin/* ; do count=$(($count+1)) ; echo $count ; done | tail -n 1
16
Metode # 3: bahasa / penerjemah lain
Python juga dapat menangani nama file yang bermasalah melalui pencetakan panjang daftar yang diberikan os.listdir()
fungsi saya (yang non-rekursif, dan hanya akan mendaftar item dalam direktori yang diberikan sebagai argumen).
$> python -c "import os ; print os.listdir('.')"
['file2.txt', 'file1.txt', 'FILE\nNAME', 'file3.txt']
$> python -c "import os ; print(len(os.listdir('.')))"
4
Lihat juga
ls | wc -l
akan gagal jika ada file dengan baris baru di nama file. Ini lebih tangguh:find . -mindepth 1 -maxdepth 1 -printf . | wc -c