Làm thế nào để chỉ liệt kê các tệp chứ không phải các thư mục của một thư mục Bash?


84

Làm cách nào tôi có thể liệt kê tất cả các tệp của một thư mục nhưng không liệt kê các thư mục hoặc tệp con của chúng. Nói cách khác: Làm cách nào để chỉ liệt kê các tệp?




Không có bản sao được đề xuất nào dường như thực hiện yêu cầu bỏ qua thư mục.
tripleee

Câu trả lời:


113

Sử dụng find:

find . -maxdepth 1 -type f

Sử dụng -maxdepth 1tùy chọn đảm bảo rằng bạn chỉ tìm trong thư mục hiện tại (hoặc, nếu bạn thay thế .bằng một số đường dẫn, thư mục đó). Nếu bạn muốn có một danh sách đệ quy đầy đủ của tất cả các tệp trong đó và các thư mục con, chỉ cần loại bỏ tùy chọn đó.


Sau khi nhận xét của tôi cho câu trả lời của mklement0, tôi nhận ra rằng "find ./*.png -maxdepth 1 -type f> pngs.txt" có thể sẽ đạt được kết quả tương tự. Nó có. Mà không cần cài đặt một tập lệnh.
Alex Hall

2
findtrên mac, không có -type, cũng không có -maxdepthtùy chọn.
Timofey

1
@Tim: -type-maxdepthkhông phải là tùy chọn theo nghĩa thông thường; BSD find(như được sử dụng trên OS X) gọi họ là bầu cử sơ bộ , và họ phải đến sau tên tập tin toán hạng (s) ( .trong trường hợp này; lưu ý rằng, không giống như trên Linux, nhu cầu phiên bản BSD ít nhất một rõ ràng filename toán hạng); lệnh trong câu trả lời này chắc chắn hoạt động trên máy Mac.
mklement0

1
@AlexHall: Đó là một giải pháp thông minh (mặc dù tôi đề nghị find *.png -maxdepth 0 -type fđể tránh ./tiền tố trong tên tập tin đầu ra; cũng lưu ý -maxdepthcủa 0, không 1), miễn là tất cả bạn cần là file tên trong thứ tự chữ cái . Nếu bạn muốn những gì lscó thể làm cho bạn (định dạng / thứ tự đầu ra khác nhau, kiểm soát nội tuyến đối với việc các mục ẩn có được đưa vào hay không), bổ sung với tính năng lọc loại [đa], tập lệnh từ câu trả lời của tôi có thể giúp ích.
mklement0

1
Ngược lại find * -maxdepth 0 -type f(một giải pháp thay thế bắt nguồn từ nhận xét của @ AlexHall) với find . -maxdepth 1 -type ftừ câu trả lời: find . ...luôn bao gồm các mục ẩn, tiền tố luôn luôn xuất ra tên tệp ./và, với GNU find(Linux), thường xuất ra danh sách không được sắp xếp. find * ..., do cho phép shell thực hiện việc lấp đầy phía trước, theo mặc định sẽ loại trừ các mục ẩn (có thể được thay đổi bằng shopt -s dotglob), chỉ xuất ra các tên tệp (không có tiền tố), được sắp xếp theo thứ tự bảng chữ cái. Cả hai cách tiếp cận đều không bao gồm các liên kết tượng trưng cho các tệp; sử dụng tùy chọn -Lđể làm như vậy.
mklement0

14
ls -p | grep -v /

ls -p cho phép bạn hiển thị / sau tên thư mục, đóng vai trò như một thẻ để bạn xóa.


Thật tuyệt khi xem một ví dụ sử dụng lsthêm vào find, vì cái sau trả về các đường dẫn tương đối và tên tệp duy nhất trước đây. Sử dụng các công cụ thích hợp cho công việc.
Ben Amos

5
  • findCâu trả lời dựa trên carlpett ( find . -maxdepth 1 -type f) hoạt động về nguyên tắc, nhưng không hoàn toàn giống với cách sử dụng ls: bạn nhận được một danh sách có khả năng không được sắp xếp gồm các tên tệp đều có tiền tố./ và bạn mất khả năng áp dụng lsnhiều tùy chọn ;
    cũng find luôn luôn tìm thấy các mục ẩn , trong khi lshành vi của phụ thuộc vào sự hiện diện hoặc vắng mặt của -ahoặc -Acác tùy chọn.

    • Một cải tiến , được đề xuất bởi Alex Hall trong một bình luận về câu hỏi là kết hợp vỏ cầu vồng vớifind :

          find * -maxdepth 0 -type f  # find -L * ... includes symlinks to files
      
      • Tuy nhiên, trong khi điều này giải quyết vấn đề tiền tố và cung cấp cho bạn đầu ra được sắp xếp theo thứ tự bảng chữ cái , bạn vẫn không có quyền kiểm soát (nội dòng) đối với việc bao gồm các mục ẩn cũng như quyền truy cập vào lsnhiều tùy chọn sắp xếp / định dạng đầu ra khác.
  • Câu trả lời ls+grep của Hans Roggeman khá thực dụng, nhưng khiến bạn không thích sử dụng -lđịnh dạng đầu ra dài ( ) .


Để giải quyết những hạn chế này, tôi đã viết tiện ích fls( f iltering ls ) ,

  • một tiện ích cung cấp tính linh hoạt của đầu rals đồng thời cung cấp khả năng lọc kiểu ,
  • đơn giản bằng cách đặt các ký tự lọc kiểu như fcho tệp, dcho thư mục và lcho các liên kết tượng trưng trước danh sách các lsđối số (chạy fls --helphoặc fls --manđể tìm hiểu thêm).

Ví dụ:

fls f        # list all files in current dir.
fls d -tA ~  #  list dirs. in home dir., including hidden ones, most recent first
fls f^l /usr/local/bin/c* # List matches that are files, but not (^) symlinks (l)

Cài đặt

Nền tảng được hỗ trợ

  • Khi cài đặt từ sổ đăng ký npm : LinuxmacOS
  • Khi cài đặt thủ công : bất kỳ nền tảng giống Unix nào với Bash

Từ sổ đăng ký npm

Lưu ý: Ngay cả khi bạn không sử dụng Node.js, trình quản lý gói của nó npm, hoạt động trên các nền tảng và dễ cài đặt; thử
curl -L https://git.io/n-install | bash

Với Node.js được cài đặt, hãy cài đặt như sau:

[sudo] npm install fls -g

Ghi chú :

  • Bạn có cần sudohay không tùy thuộc vào cách bạn cài đặt Node.js / io.js và liệu bạn có thay đổi quyền sau đó hay không ; nếu bạn gặp EACCESlỗi, hãy thử lại với sudo.

  • Các -gđảm bảo toàn cầu cài đặt và là cần thiết để đặt flstrong hệ thống của bạn $PATH.

Hướng dẫn cài đặt

  • Tải xuống tập lệnh nàybash dưới dạng fls.
  • Làm cho nó có thể thực thi với chmod +x fls.
  • Di chuyển nó hoặc liên kết biểu tượng nó vào một thư mục trong của bạn $PATH, chẳng hạn như /usr/local/bin(macOS) hoặc /usr/bin(Linux).

1
Xuất sắc. Ngay cả khi nó liên quan đến việc tạo một tập lệnh khác. Tôi đã sao chép và dán từ nguồn văn bản thuần túy mà bạn liên kết đến, vào một tệp văn bản và chạy nó trong Cygwin bằng lệnh này: fls.sh f * .png> pngs.txt Và bingo: danh sách các tệp .png không có đường dẫn. Nhưng thực sự, ls không có một tùy chọn nào có thể so sánh với công tắc "dir / b" của DOS? Tôi đã xem qua nội dung của đầu ra ls '--help, và ít nhất là không có gì thuộc loại này.
Alex Hall

1
@AlexHall: Cảm ơn; tl; dr: thử -1(số một); lsthực sự mặc định cho đầu ra "trống", tức là chỉ có tên tệp, nhưng khi xuất ra thiết bị đầu cuối sử dụng bố cục dựa trên cột (nhiều tên tệp trên mỗi dòng). Để nhận một tên tệp cho mỗi dòng đầu ra (đó là những gì dir /bsẽ xảy ra, nếu bộ nhớ phục vụ), hãy sử dụng -1tùy chọn này, thực sự được ngầm định khi stdout không được kết nối với thiết bị đầu cuối, chẳng hạn như khi gửi đến một đường ống hoặc tệp đầu ra.
mklement0

2

Liệt kê nội dung của một số thư mục, không có thư mục con

Tôi thích sử dụng lscác tùy chọn, ví dụ:

  • -l sử dụng một định dạng danh sách dài
  • -t sắp xếp theo thời gian sửa đổi, mới nhất trước
  • -r đảo ngược thứ tự trong khi sắp xếp
  • -F, --classify nối chỉ báo (một trong số * / => @ |) vào các mục nhập
  • -h, --human-readable với -l và -s, các kích thước in như 1K 234M 2G, v.v.

Đôi khi --colorvà tất cả những người khác. (Xem ls --help)

Liệt kê mọi thứ trừ thư mục

Điều này sẽ hiển thị các tệp, liên kết tượng trưng, ​​thiết bị, đường dẫn, ổ cắm, v.v.

vì thế

find /some/path -maxdepth 1 ! -type d

có thể được sắp xếp theo ngày một cách dễ dàng:

find /some/path -maxdepth 1 ! -type d -exec ls -hltrF {} +

Chỉ các tệp danh sách :

hoặc là

find /some/path -maxdepth 1 -type f

sắp xếp theo kích thước:

find /some/path -maxdepth 1 -type f -exec ls -lSF --color {} +

Ngăn chặn danh sách các mục nhập bị ẩn :

Để không hiển thị các mục bị ẩn, trong đó tên bắt đầu bằng dấu chấm, bạn có thể thêm ! -name '.*':

find /some/path -maxdepth 1 ! -type d ! -name '.*' -exec ls -hltrF {} +

Sau đó

Bạn có thể thay thế /some/pathbằng .để liệt kê cho thư mục hiện tại hoặc ..cho thư mục mẹ .


1

Bạn cũng có thể sử dụng lsvới grephoặc egrepvà đặt nó trong hồ sơ của mình làm bí danh:

ls -l | egrep -v '^d'
ls -l | grep -v '^d'

Tôi sẽ không đặt điều này trong một tập lệnh vì lý do được đưa ra ở trên, mà là một giải pháp nhanh chóng và bẩn thỉu khác: ls -F | grep -v '/ $'
mooie

1

tìm tệp: ls -l / home | grep "^ -" | tr -s '' | cut -d '' -f 9

tìm thư mục: ls -l / home | grep "^ d" | tr -s '' | cut -d '' -f 9

tìm liên kết: ls -l / home | grep "^ l" | tr -s '' | cut -d '' -f 9

tr -s '' biến đầu ra thành tệp được phân cách bằng dấu cách, lệnh cut cho biết dấu phân cách là dấu cách và trả về trường thứ 9 (luôn là tên tệp / tên thư mục / tên liên kết).

Tôi sử dụng tất cả các thời gian!


Chà! Điều gì sẽ xảy ra nếu tên tệp chứa khoảng trắng?
F. Hauri

0
{ find . -maxdepth 1 -type f | xargs ls -1t | less; }

được thêm vào xargsđể làm cho nó hoạt động và được sử dụng -1thay vì -lchỉ hiển thị tên tệp mà không có lsthông tin bổ sung


Này có một số bằng khen, trong đó nó thực thi sắp xếp theo thời gian, mặc dù có được cho là cách ít vụng về để làm điều đó vớifind -printf0 '...' | sort -z
tripleee

-2

Chỉ thêm vào câu trả lời của carlpett. Để có một cái nhìn hữu ích về các tệp, bạn có thể chuyển đầu ra thành ls.

find . -maxdepth 1 -type f|ls -lt|less

Hiển thị các tệp được sửa đổi gần đây nhất ở định dạng danh sách, khá hữu ích khi bạn đã tải xuống nhiều tệp và muốn xem phiên bản không lộn xộn của những tệp gần đây.


3
Điều này có thể không hoạt động như bạn mong đợi! lskhông đọc đầu vào tiêu chuẩn, vì vậy sẽ vô ích khi chuyển bất kỳ thứ gì đến ls. Bạn đã bỏ lỡ xargs?
gniourf_gniourf

Nói cách khác: findlệnh trong câu trả lời này hoàn toàn bị bỏ qua ; lệnh tổng thể giống như ls -lt | less, không thực hiện lọc kiểu.
mklement0

1
Mặc dù với GNU findbạn có thể làm được find . -maxdepth 1 -type f -ls. Nó dường như cũng hoạt động trên Mac OS, mặc dù tôi tin rằng -maxdepth-lskhông phải là tùy chọn di động thích hợp.
tripleee

-2

"find '-maxdepth'" không hoạt động với phiên bản bash cũ của tôi, do đó tôi sử dụng:

cho f trong $ (ls); làm nếu [-f $ f]; sau đó echo $ f; fi; làm xong


Việc sử dụng for f in $(ls)là sai gấp đôi. Bạn có thể khắc phục điều đó bằng for f in *nhưng sau đó nó sẽ bị hỏng vì bạn không trích dẫn đối số echomột cách chính xác.
tripleee
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.