user4556274 đã trả lời những lý do tại sao . Câu trả lời của tôi chỉ phục vụ để cung cấp thêm thông tin cho thế nào để đếm đúng file.
Trong cộng đồng Unix, sự đồng thuận chung là phân tích cú pháp đầu ra ls
là một ý tưởng rất tồi , vì tên tệp có thể chứa các ký tự điều khiển hoặc ký tự ẩn. Ví dụ: do một ký tự dòng mới trong tên tệp, chúng tôi đã ls | wc -l
cho chúng tôi biết có 5 dòng trong đầu ra của ls
(mà nó có), nhưng thực tế chỉ có 4 tệp trong thư mục.
$> touch FILE$'\n'NAME
$> ls
file1.txt file2.txt file3.txt FILE?NAME
$> ls | wc -l
5
Phương pháp # 1: tìm tiện ích
Các find
lệnh, mà thường được sử dụng để làm việc xung quanh phân tích cú pháp tên tập tin, có thể giúp chúng ta ở đây bằng cách in các số inode . Có thể là một thư mục hoặc một tập tin, nó chỉ có một số inode duy nhất. Do đó, sử dụng -printf "%i\n"
và loại trừ .
thông qua -not -name "."
chúng tôi có thể có số lượng chính xác của các tệp. (Lưu ý việc sử dụng -maxdepth 1
để ngăn đệ quy giảm dần vào các thư mục con)
$> 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
Phương pháp # 2: sao
Cách đơn giản, nhanh chóng và chủ yếu là di động:
$ set -- *
$ echo $#
228
set
lệnh được sử dụng để đặt tham số vị trí của shell (các $<INTEGER>
biến, như trong echo $1
). Điều này thường được sử dụng để làm việc xung quanh việc /bin/sh
hạn chế thiếu mảng. Một phiên bản thực hiện kiểm tra bổ sung có thể được tìm thấy trong câu trả lời của Gille trên Unix & Linux.
Trong shell hỗ trợ mảng, chẳng hạn như bash
, chúng ta có thể sử dụng
items=( dir/* )
echo ${#items[@]}
như đề xuất của Steeldo trong các ý kiến .
Thủ thuật tương tự với find
phương thức được sử dụng wc
và globalstar có thể được sử dụng stat
để đếm số lượng inode trên mỗi dòng:
$> LC_ALL=C stat ./* --printf "%i\n" | wc -l
4
Một cách tiếp cận khác là sử dụng ký tự đại diện trong for
vòng lặp. (Lưu ý, kiểm tra này sử dụng một thư mục khác để kiểm tra xem phương pháp này có đi vào thư mục con hay không - 16 là số mục được xác minh trong mục của tôi ~/bin
)
$> count=0; for item in ~/bin/* ; do count=$(($count+1)) ; echo $count ; done | tail -n 1
16
Phương pháp # 3: ngôn ngữ / thông dịch viên khác
Python cũng có thể xử lý các tên tệp có vấn đề thông qua việc in độ dài của danh sách được cung cấp cho os.listdir()
hàm của tôi (không phải là đệ quy và sẽ chỉ liệt kê các mục trong thư mục được cung cấp dưới dạng đối số).
$> python -c "import os ; print os.listdir('.')"
['file2.txt', 'file1.txt', 'FILE\nNAME', 'file3.txt']
$> python -c "import os ; print(len(os.listdir('.')))"
4
Xem thêm
ls | wc -l
sẽ thất bại nếu có các tệp có dòng mới trong tên tệp. Điều này là kiên cường hơn:find . -mindepth 1 -maxdepth 1 -printf . | wc -c