Lệnh 'ls -d' không hiển thị các thư mục. Có cách nào để 'ls' chỉ hiển thị các thư mục thay vì các tệp và thư mục không?


44

Có cách nào để lschỉ hiển thị các thư mục thay vì các tập tin và thư mục?

Từ trang người đàn ông:

   -d, --directory
          list directory entries instead of contents, and do not  derefer
          ence symbolic links

Vì vậy, nếu tôi gõ nó vào /thư mục tôi sẽ chỉ thấy các thư mục. Thay vào đó, nó hiển thị "."

$ cd /
$ ls -d
.

Tôi đã mong đợi ls -dđể cho tôi thấy điều này:

$ ls -d
bin    data  home        opt    sbin  sys      var
boot   dev   lib         media  proc  selinux  tmp
cdrom  etc   lost+found  mnt    root  srv      usr

Có cách nào để lschỉ hiển thị các thư mục thay vì các tập tin và thư mục?


17
lsd thể rất khó hiểu.
boehj

2
@jin ls -d * / công trình. Nhưng tại sao tôi phải "* /" để đưa ra những gì tôi muốn.
nelaaro

8
@nelaar -dkhông có nghĩa là chỉ liệt kê các thư mục, nó có nghĩa là không liệt kê nội dung thư mục. Hãy thử gõ ls */và bạn sẽ thấy nội dung của tất cả các thư mục.
Jin

2
Tôi đã ldircố ls -d */gắng .bashrcđể làm điều này dễ dàng hơn ...
DQdlM

1
ls có thể cung cấp cho bạn hàng tấn thông tin nhưng không phải là một lá cờ duy nhất cho việc chỉ hiển thị các thư mục ...
DimiDak

Câu trả lời:


50

Mong đợi của bạn dựa trên DOS Think / Windows Think và sai. Trên MS-DOS, Windows và một số hệ điều hành IBM / Microsoft khác, việc mở rộng ký tự đại diện được thực hiện bằng chính lệnh và những thứ như /atùy chọn cho dirlệnh đóng vai trò là bộ lọc thuộc tính trong quá trình mở rộng ký tự đại diện. dirmở rộng các ký tự đại diện như *, mà trình thông dịch lệnh truyền cho nó như hiện tại và nếu /ađược chỉ định, nó sẽ áp dụng các bộ lọc thích hợp cho những gì được trả về. (Trên một số hệ điều hành, các bộ lọc thuộc tính có thể được cung cấp cho lệnh gọi hệ thống để liệt kê một thư mục và nhân hệ điều hành hoặc trình điều khiển hệ thống tệp của nó, áp dụng chính chúng.)

Trên Unices và trên Linux, việc mở rộng ký tự đại diện được thực hiện bởi trình bao và không chú ý đến các quyền. Khi, trong thư mục gốc, bạn làm

ls *

những gì lsbản thân lệnh nhận được từ shell là gì

ls bin home opt var boot dev tmp vv bị mất + tìm thấy root usr

Những gì -d/ --directorytùy chọn làm là tắt những gì thường xảy ra tiếp theo . Điều thường xảy ra tiếp theo là lslần lượt xem xét từng đối số của nó, thấy rằng chúng là các thư mục và quyết định liệt kê nội dung của chúng. Đối với các đối số có tên tệp, nó chỉ in ra thông tin cho chính tệp đó. Với -dtùy chọn, các thư mục được xử lý giống như các tập tin. Vì vậy, lsin ra thông tin cho từng thư mục được truyền dưới dạng đối số của nó, giống như nó sẽ làm nếu chúng là tệp.

Vì vậy, -d không phải là một tùy chọn "chỉ in thư mục". Trong thực tế, không chỉ không có lựa chọn như vậy; không thể có một lựa chọn như vậy. Việc mở rộng ký tự đại diện được thực hiện bởi trình bao và shít nhất (trong POSIX ) không có cách nào để trình bày trình bao để kiểm tra quyền và bit loại tệp khi mở rộng *thành danh sách tên. Để có được danh sách tên của các thư mục một mình, cần phải sử dụng findlệnh, như được giải thích bởi ztank1013, hoặc sử dụng thủ thuật mà tên đường dẫn kết thúc bằng dấu gạch chéo ngụ ý mục nhập thư mục ., như được giải thích bởi Jin. ( JinTrò lừa bịp kết thúc bằng lslệnh nhận các đối số

ls bin / home / opt / var / boot / dev / tmp / etc / Mất + tìm thấy / root / usr /

bởi vì mẫu */trên thực tế khớp tên đường dẫn với hai thành phần, phần thứ hai trống và do đó không hoàn toàn làm những gì mong muốn. Cụ thể, nó sẽ coi các liên kết tượng trưng chỉ đến các thư mục như thể chúng là các thư mục.)

Hành vi ls -dkhông có a *là một phần mở rộng đơn giản ở trên. Một cách đơn giản là phải biết thêm một điều nữa ls: Khi nó không được đưa ra đối số, nó sẽ thừa nhận một đối số mặc định là .. Bây giờ mà không cần sự -dlựa chọn, hành vi nói trên dẫn đến nội dung của thư mục được đặt tên bởi .được liệt kê và thông tin cho nội dung của nó được hiển thị. Với các -dtùy chọn, thư mục .được đối xử giống như thể nó là một tập tin, và các thông tin riêng của mình được hiển thị, chứ không phải là nội dung của nó được liệt kê.


3
" Không thể có một tùy chọn như vậy" - đó là một tuyên bố khá mạnh mẽ - việc thực hiện một tùy chọn như vậy là hiển nhiên: xem một đối số không phải là thư mục và bỏ qua nó. Những gì không thể thực hiện là tương đương với dir /s *.txt[mà không cần dùng đến trích dẫn ký tự đại diện như tìm kiếm]
Random832

6
Đúng, nhưng không có lý do logic nào. Tôi không thể có một tùy chọn sẽ lọc ra các mục được truyền vào dưới dạng đối số. Thực tế là "mở rộng ký tự đại diện được ly dị từ loại nhập kiểm tra" là không thích hợp, vì đây không có gì ở tất cả để làm với ký tự đại diện mở rộng - chỉ loại nhập kiểm tra, mà không có lý do nó không thể được thực hiện hoàn toàn trong vòng ls. Nếu ls --color có thể tô màu xanh cho chúng, ls -F có thể đặt a / sau chúng và ls -l có thể đặt 'd' trong chế độ, sau đó một số tùy chọn giả thuyết khác có thể bỏ qua chúng. Tùy chọn như vậy không tồn tại không có nghĩa là " không thể ".
Random832

5
Random832 đưa ra một quan điểm đúng đắn: ls có thể có một tùy chọn để lọc các tệp hoặc thư mục và điều này không loại trừ lẫn nhau khi có trình bao mở rộng. Không có điều kiện cuộc đua trong ls: nó có thể lọc nó khi nó thống kê các tệp bình thường. (Đã có một cuộc đua giữa việc mở rộng shell và ls, FWIW.) Tôi nghĩ rằng việc mở rộng shell chỉ là một phần lý do: mở rộng shell (và lọc nói chung) không được thực hiện trong ls vì nó sẽ cần được thực hiện lại trong cp , mv, v.v. Unix là "làm một việc và làm tốt". Nếu bạn cần lọc nâng cao, có những công cụ cho việc đó.
Thanatos

2
Các ls -ptùy chọn thêm một /biểu tượng để chỉ thư mục. Không có lý do gì để không mở rộng khả năng in đầu ra với thứ chỉ xuất ra những thứ này (chứ không phải ls -p | grep /).
Anne van Rossum

3
@JdeBP, các cuộc tấn công ad-hominem ("kiddo") và sự kiêu ngạo (tất cả mọi người trừ bạn không biết "các nguyên tắc cơ bản của Unix") không thuộc về một cuộc thảo luận kỹ thuật. Hơn nữa, bạn đang kéo một người rơm khi bạn cho rằng một tùy chọn lệnh không thể kiểm soát việc mở rộng ký tự đại diện được thực hiện bằng shell. Tất nhiên là không thể! Cả Random832, cũng không phải Thanatos, cũng không phải Anne van Rossum, và thậm chí cả câu hỏi cũng không đề cập đến các ký tự đại diện theo bất kỳ cách nào. Sự phản đối là ls --only-directories .tùy chọn đó có thể được thêm vào lscuối cùng.
mkalkov

30

Bạn có thể sử dụng ls -d */, hoặc ls -d .*/cho các thư mục ẩn.


mẹo thông minh bằng cách sử dụng /!
Mono

Vâng, điều này là tốt. Có trường hợp nào điều này không hoạt động?
iyrin

5
+1 để cung cấp câu trả lời trong một dòng. Tôi đoán câu trả lời được chấp nhận cũng có nó, ở đâu đó.
Giải tích Hiệp sĩ

Làm thế nào bạn có thể sử dụng điều này trong một kịch bản mà không có trong thư mục?
DimiDak

13

Thử đi

 find . -mindepth 1 -maxdepth 1 -type d

để chỉ nhận các thư mục dưới vị trí hiện tại của bạn.


5

Bạn cũng có thể thích

tree -d 

trong đó liệt kê gọn gàng tất cả các thư mục và thư mục con với mô tả đồ họa của cấu trúc cây.


3
Và chỉ sâu một cấp:tree -dL 1
Anne van Rossum

Thật không may, bạn không thể kết hợp nhiều với cây. # cây -d | grep wc -l (đầu vào tiêu chuẩn)
DimiDak

5

Nếu bạn muốn xem các thư mục chỉ với ls -ltùy chọn chi tiết như (ELL) thì bạn có thể sử dụng bên dưới:

find -maxdepth 1 -type d -ls;

Ở trên sẽ chỉ cung cấp cho bạn các chi tiết như bạn nhận được với -ltùy chọn.


1
Nó có thể còn tốt hơn để sử dụng find -maxdepth 1 -type d -exec ls -d {} +để có được đầu ra ở lsđịnh dạng thông thường .
mkalkov

4

Nếu bạn muốn hoàn thành công việc theo cách khác, hãy thử điều này:

ls -l | grep ^d

Mặc dù một công cụ duy nhất là đủ trong tình huống này. Đường ống luôn luôn có mặt để giúp bạn. Tôi thích sự linh hoạt trong Linux, điều mà tôi muốn bạn làm.


1
Điều này sẽ lọc ra nhiều hơn thư mục.
ocodo

2
@Slomojo, điều này sẽ lọc ra mọi thứ trừ thư mục. Bạn có ý gì?
mkalkov

Vâng, bạn cần -l (dài) để các quyền truy cập vào dòng. "d" cho thư mục. Thêm vào đó bạn nhận được một danh sách "dài" của một mục thư mục là tốt đẹp.
GeoO

1

Tôi hy vọng điều này sẽ khắc phục nhu cầu của bạn. Lệnh dưới đây sẽ chỉ liệt kê các thư mục trong một đường dẫn nhất định.

ls -F <path> | grep /

Thí dụ:

ls -F ~ | grep /
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.