Tôi có thể xác định số lượng thư mục con trong một thư mục bằng cách sử dụng `ls -l` không?


8

Khi hiển thị các thư mục bằng cách sử dụng ls -l, số lượng liên kết của chúng (trường thứ hai trong đầu ra) ít nhất là hai: một cho tên dir và một cho.

$ mkdir foo
$ ls -l
total 2
drwxr-xr-x  2 user   wheel  512  4 oct 14:02 foo

Có an toàn không khi luôn cho rằng số lượng liên kết trên 2 tương ứng với số lượng thư mục con trong thư mục này ( ..liên kết)?

Câu trả lời:


7

Điều này thường đúng trên các hệ thống unix rằng số lượng liên kết đến một thư mục là số lượng thư mục con cộng với 2. Tuy nhiên, có những trường hợp điều này không đúng:

  • Một số thống nhất cho phép liên kết cứng đến thư mục. Sau đó, sẽ có nhiều hơn 2 liên kết không tương ứng với các thư mục con.

  • Có các hệ thống tập tin nơi các thư mục không có mục cho .... Các GNU tìm thủ đề cập đến một số ví dụ trong phần thảo luận của nó -noleaftùy chọn (giúp chặn đứng một tối ưu hóa mà giả định rằng ...tồn tại trong tất cả các thư mục): “CD-ROM hoặc MS-DOS hệ thống tập tin hoặc AFS khối lượng gắn kết điểm”

Một cách gần như đáng tin cậy để đếm số lượng thư mục con (vẫn có thể thất bại nếu tên tệp chứa ký tự dòng mới) là

$(($(LC_ALL=C ls -la /path/to/directory | grep '^d' | wc -l) - 2)

Một cách đáng tin cậy hơn sử dụng các khối vỏ */.*/; như thông thường xử lý trường hợp mẫu không khớp là một chút khó khăn (ngoại trừ trong bash và zsh nơi bạn có thể bật nullglobtùy chọn).


2

Đây là một cách khác để đếm các thư mục con (không đệ quy) trong Bash:

(
shopt -s nullglob dotglob
printf '%s\000' */ | tr -dc '\0' | wc -c  # wc counts null bytes
)

Vì mỗi tên tệp đang bị chấm dứt bởi một ký tự ASCII NUL, nên tên này sẽ hoạt động chính xác ngay cả khi tên tệp chứa ký tự dòng mới.



1

Tôi không thể tìm thấy bất cứ điều gì trong tài liệu xác nhận rằng số lượng liên kết sẽ luôn là +2 trên số lượng thư mục con.

Nhưng, để tìm ra số đạn chính xác, hãy sử dụng:

find . -type d -mindepth 1  -maxdepth 1 | wc -l

Hoặc nếu bạn phải sử dụng ls -l, xem câu trả lời khác.


Tôi nghĩ bạn có ý đó -type d, nhưng: 1. điều này đòi hỏi GNU find; 2. bạn cần trừ 1 cho thư mục bắt đầu (hoặc vượt qua -mindepth 1).
Gilles 'SO- ngừng trở nên xấu xa'

0

Đừng sử dụng lscho việc này . Đây là một cách hoạt động với tất cả tên tệp, ngay cả những tên chứa dòng mới, bởi vì nó chỉ in một ký tự dòng mới thay vì tên tệp:

find . -mindepth 1 -maxdepth 1 -type d -printf '\n' | wc -l

Chỉnh sửa: Phiên bản hiện tại không dẫn đến bất kỳ cảnh báo nào, bởi vì -mindepth-maxdepthnên có trước -type(cây thư mục được cắt tỉa trước khi kiểm tra thư mục, để tiết kiệm thời gian).

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.