Chỉ liệt kê các tệp thông thường (nhưng không phải thư mục) trong thư mục hiện tại


126

Tôi có thể sử dụng ls -ld */để liệt kê tất cả các mục thư mục trong thư mục hiện tại. Có cách nào tương tự dễ dàng để chỉ liệt kê tất cả các tệp thông thường trong thư mục hiện tại không? Tôi biết tôi có thể sử dụng tìm

find . -maxdepth 1 -type f

hoặc stat

stat -c "%F %n" * | grep "regular file" | cut -d' ' -f 3-

nhưng những điều này không đánh tôi là quá thanh lịch. Có một cách ngắn gọn để chỉ liệt kê các tệp thông thường (tôi không quan tâm đến các thiết bị, đường ống, v.v.) chứ không phải các thư mục con của thư mục hiện tại? Liệt kê các liên kết tượng trưng cũng sẽ là một điểm cộng, nhưng không phải là một điều cần thiết.


5
Bạn có ý nghĩa gì bởi "quá thanh lịch"? Theo tôi biết, findlệnh là cách tốt nhất để làm những gì bạn muốn. Đối với một số tùy chọn đáng tin cậy khác, bạn nên xem xét các lệnh cụ thể của shell (và đó là bất cứ thứ gì ngoại trừ di động)!
rahmu

@rahmu Tôi đã cho một cái gì đó tương tự ls -d */, ngắn, dễ gõ và dễ hiểu. Vì vậy, tôi khá hài lòng với câu trả lời của Ulrich Dangel, mặc dù tôi không sử dụng zsh.
daniel kullmann

Câu trả lời:


32

Với zshVòng loại Glob, bạn có thể dễ dàng thể hiện trực tiếp, ví dụ:

echo *(.)

sẽ chỉ trả về danh sách các tệp thông thường hoặc lỗi tùy thuộc vào cấu hình của bạn.

Đối với các thư mục không:

echo *(^/)

(sẽ bao gồm các liên kết tượng trưng (bao gồm cả thư mục), tên ống, thiết bị, ổ cắm, cửa ...)

echo *(-.)

cho các tập tin thường xuyên và symlink đến tập tin thông thường.

echo *(-^/)

cho các thư mục không và không có liên kết đến các thư mục.

Ngoài ra, hãy xem Dvòng loại toàn cầu nếu bạn muốn bao gồm các tệp D ot (các tệp ẩn), như thế nào *(D-.).


170
ls -p | grep -v / 

Lệnh này liệt kê tất cả các tệp không bị ẩn mà không phải là thư mục (tệp thông thường, liên kết, tệp thiết bị , v.v.). Để bao gồm các tệp ẩn, thêm -Atùy chọn vàols

Nó giả sử không có tệp nào có ký tự dòng mới trong tên của chúng. Thêm -qtùy chọn để lschuyển đổi tất cả các ký tự không in được, kể cả dòng mới sang ?, đảm bảo chúng nằm trên một dòng và rất phù hợp để cung cấp cho tiện ích dựa trên dòng như grepvà để in trên thiết bị đầu cuối.


14
+1, đây là một câu trả lời tốt. Bỏ phiếu cho một người dùng mới không có bình luận là khá sốc đối với tôi, đặc biệt là khi câu trả lời hoạt động được cung cấp. Trường hợp cạnh duy nhất tôi có thể thấy nơi này sẽ không hoạt động chính xác là nếu có một dòng mới trong tên tệp. Ngoài ra giữ lại màu sắc sẽ là một bổ sung tốt đẹp khi được hỗ trợ. Đối với GNU, bạn có thể thêm --color=alwaysvào ls, cho OSX -G.
Graeme

Xin chào, lệnh bạn đã đưa ra rất tuyệt và nó chắc chắn giúp tôi hiểu tuy nhiên tôi đã tự hỏi liệu có thể sử dụng lệnh trên và thay đổi quyền truy cập tệp cùng một lúc không? sudo chmod 777Cuối cùng tôi đã thử thêm vào và tôi đã nhận được lỗi ... Mọi sự trợ giúp đều được đánh giá cao
disidia

3
Nếu bạn cũng muốn loại trừ các liên kết tượng trưng trỏ đến thư mục ls -pL | grep -v /. Các -Lliên kết tượng trưng thêm vào .
Matthias Braun

1
Nếu bạn cũng thích sử dụng bộ lọc ký tự đại diện, hãy làm ls -pdL something* | grep -v /. -dTùy chọn được thêm vào liệt kê các thư mục, không phải nội dung của chúng, vì vậy chúng sẽ bị loại trừ một cách chính xác.
Rockallite

Và nếu bạn muốn lấy tất cả các tệp mà không có thư mục, chỉ cần xóa -v
jasonleonhard

23

Để chỉ liệt kê các tệp thông thường:

ls -al | grep '^-'

Với các liên kết tượng trưng (đến bất kỳ loại tệp nào) bao gồm:

ls -al | grep '^[-l]'

Trong đó ký tự đầu tiên của danh sách mô tả loại tệp, -có nghĩa là đó là tệp thông thường, cho liên kết tượng trưng là l.

Debian / Ubuntu

In tên của tất cả các tệp phù hợp (bao gồm các liên kết):

run-parts --list --regex . .

Với đường dẫn tuyệt đối:

run-parts --list --regex . "$PWD"

In tên của tất cả các tệp trong /etcđó bắt đầu bằng pvà kết thúc bằng d:

run-parts --list --regex '^p.*d$' /etc

15

lskhông có tùy chọn để làm điều đó, nhưng một trong những điều hay của unix & linux là các đường ống dài và không linh hoạt có thể dễ dàng được chuyển thành tập lệnh shell, hàm hoặc bí danh. và những thứ này có thể được sử dụng trong các đường ống giống như bất kỳ chương trình nào khác.

(LƯU Ý: có một số vấn đề về phạm vi với các hàm và bí danh. Các tập lệnh có sẵn cho bất kỳ tập tin thực thi nào có thể đọc và thực thi chúng. Ngoài ra, một tập lệnh có thể được viết bằng bất kỳ ngôn ngữ nào - bao gồm bash / sh, awk, perl, python và các ngôn ngữ khác - bất kỳ tập lệnh nào phù hợp nhất với công việc hoặc bạn quen thuộc nhất với công việc)

ví dụ

alias lsf='find . -maxdepth 1 -type f -print0 | xargs -0r ls'

Tôi đã thêm xargs để bạn có thể sử dụng tất cả các lstùy chọn thông thường , ví dụ:lsf -lrS

Bởi vì nó sử dụng find, tất cả các dotfiles ẩn thông thường sẽ được hiển thị và tất cả các tên tệp sẽ được thêm tiền tố ./ - đó là về sự khác biệt duy nhất bạn sẽ nhận thấy.

Bạn có thể loại trừ các tệp chấm với ! -iname '.*'nhưng sau đó bạn phải có hai phiên bản bí danh - một phiên bản hiển thị tệp chấm và một phiên bản không có.

alias lsf2='find . -maxdepth 1 -type f -a ! -iname '\''.*'\'' -print0 | xargs -0r ls'

Ngoài ra, nếu lsflà một tập lệnh chứ không phải là bí danh, bạn có thể phân tích các tùy chọn (có thể bằng getopts hoặc / usr / bin / getopt hoặc tương tự), và loại trừ dotfiles trừ khi -acó mặt.


-namelà đủ, bạn không cần -iname.
Típ

8
bash-4.2$ ls -F | grep -v '[/@=|]$' | more

Tùy chọn -F để ls gắn thêm * vào các tệp thực thi, / vào thư mục, @ vào các liên kết tượng trưng, ​​= vào các ổ cắm và | đến các năm Sau đó, bạn có thể sử dụng grep để loại trừ các ký tự tệp không thường xuyên khỏi đầu ra và bạn có các tệp. Điều này sẽ làm việc trong bất kỳ shell, không chỉ zsh.

Những điểm yếu là:

  1. Bất kỳ tập tin có tên kết thúc bằng @, =hoặc |sẽ được loại trừ (nhưng bạn nên không thực sự có tập tin với những ký tự trong tên anyway)
  2. Điều đó không loại trừ các tệp thiết bị hoặc một số loại tệp kỳ lạ trên một số hệ thống như cửa ra vào.
  3. Bạn sẽ có dấu hoa thị trên bất kỳ tệp nào có thể thực thi được. Điều đó có thể được xử lý bằng cách chuyển qua đường dẫn để loại bỏ bất kỳ ký tự '*' nào khỏi đầu ra.
  4. Điều đó không hoạt động đúng nếu có tên tệp chứa ký tự dòng mới.

Trên hệ thống Tôi đang viết này trên, 10% của các tập tin có tên chứa =, @hoặc |ký tự. =là phổ biến trong maildir hoặc tên tệp có phần mã hóa base64 hoặc trích dẫn có thể in được. @trong định nghĩa miền địa phương, cho địa chỉ email và nhiều hơn nữa. Thật hiếm khi chúng xuất hiện ở cuối tên tập tin. (chỉ có 31 trong số 2,2 triệu trên hệ thống này)
Stéphane Chazelas

3

Hướng dẫn cho biết tùy chọn 'f' chỉ chống lại 'tệp thông thường', không phải đường ống, ổ cắm hoặc khối / thiết bị char, có nghĩa là bạn đã làm đúng công cụ.

   -type c
          File is of type c:

          b      block (buffered) special

          c      character (unbuffered) special

          d      directory

          p      named pipe (FIFO)

          f      regular file

          l      symbolic link; this is never true if the -L option or the
                 -follow option is in effect, unless the symbolic link  is
                 broken.  If you want to search for symbolic links when -L
                 is in effect, use -xtype.

          s      socket

          D      door (Solaris)

0

Điều này không đặc biệt ngắn nhưng bạn có thể biến nó thành một tập lệnh hoặc bí danh nếu bạn cần gọi nó một cách nhanh chóng. Sử dụng lệnh ls làm mảng đầu vào, gọi ls -ld trên mỗi mục nhập được chuyển sang grep để loại trừ các thư mục có đầu ra được gửi tới null và nếu thành công lặp lại đầu vào ban đầu:

for list in `ls` ; do ls -ld $list | grep -v ^d > /dev/null && echo $list ; done ;

Bạn có thể đảo ngược grep và đầu ra có điều kiện, cùng kết quả:

for list in `ls` ; do ls -ld $list | grep ^d > /dev/null || echo $list ; done ;

\dev\null?!?!
thao tác


0

Đây là một chủ đề hơi cũ, nhưng cách sạch nhất để chỉ liệt kê các tập tin.

ls -al | grep '^-' | awk '{print $9}'


1
touch "some file name"để xem một ví dụ nhanh
Jeff Schaller

@JeffSchaller Bạn có một điểm hợp lệ. Cho rằng một cái gì đó như thế này. ls -al | grep '^-' | awk '{ for(i=9; i<=NF; ++i) printf $i""FS; print "" }', nên xử lý các tập tin với không gian trong đó.
RJ
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.