Liệt kê các tệp có phần mở rộng nhất định với ls và grep


152

Tôi chỉ muốn lấy các tệp từ thư mục hiện tại và chỉ xuất các tệp .mp4 .mp3 .exe không có gì khác. Vì vậy, tôi nghĩ rằng tôi có thể làm điều này:

ls | grep \.mp4$ | grep \.mp3$ | grep \.exe$

Nhưng không, vì grep đầu tiên sẽ chỉ xuất ra mp4 cho 2 grep kia sẽ không được sử dụng.

Có ý kiến ​​gì không? PS, Chạy đoạn script này trên Slow Leopard.


1
Đây thực sự là cách tiếp cận sai - thay vì sử dụng grep, hãy sử dụng shopt -s nullglobvà sau đó chỉ cần tham khảo *.exe *.mp3 *.mp4. Xem mywiki.wooledge.org/ParsingLs
Charles Duffy

1
Tôi không thể biết liệu "Báo chậm" có phải là một lỗi đánh máy hay không ...
Wowfunhappy

1
@Wowfunhappy hahaha, chắc chắn là một lỗi đánh máy, tôi nhớ lại rằng Snow Leopard khá nhanh.
Bạc hà

Câu trả lời:


335

Tại sao không:

ls *.{mp3,exe,mp4}

Tôi không chắc mình đã học nó ở đâu - nhưng tôi đã sử dụng nó.


1
Điều này không hiệu quả với tôi vì phần mở rộng tôi đang sử dụng là dành cho một thư mục, vì vậy ls đang liệt kê nội dung của thư mục.
Richard Venable

1
@RichardVenable thêm khóa chuyển đổi -d để ngăn các thư mục được đệ quy.
Carlos Eugenio Thompson Pinzón

11
Tôi thích giải pháp này nhưng dường như thất bại nếu bạn thiếu bất kỳ một trong các kiểu tệp. Ví dụ: bạn có mp3 nhưng không có .exe (Mac OSX, zsh)
JHo

2
Tôi đã chuyển hướng stderr thành / dev / null để tránh, ls: *.exe: No such file or directoryví dụ:ls *.{zip,tar.gz,tar} 2>/dev/null
Isaac

1
Khi tôi chạy trực tiếp ls foo *. {Tar.gz, zip} trong một trình bao, nó hoạt động, nhưng khi đặt nó vào trong tập lệnh shell mới nhất = $ (ls -I ' .done' -tr $ {pkgprefix} . {Tar. gz, zip} | tail -1) Tôi nhận được thông báo lỗi: ls: không thể truy cập 'bamtools *. {tar.gz, zip}': Không có tệp hoặc thư mục như vậy, bất kỳ anh chàng thông minh hơn nào cũng có thể tinh chỉnh câu trả lời.
Kemin Zhou

41

Sử dụng biểu thức chính quy với find:

find . -iregex '.*\.\(mp3\|mp4\|exe\)' -printf '%f\n'

Nếu bạn đang đặt tên tệp:

find . -iregex '.*\.\(mp3\|mp4\|exe\)' -printf '%f\0' | xargs -0 dosomething

Điều này bảo vệ tên tệp có chứa khoảng trắng hoặc dòng mới.

OS X findchỉ hỗ trợ luân phiên khi -Etùy chọn (nâng cao) được sử dụng.

find -E . -regex '.*\.(mp3|mp4|exe)'

2
Trên Mac OS X:find . -iregex '.*\(mp3\|mp4\|exe\)'
andilabs

3
andi, điều đó không làm việc cho tôi trên mac os. Nhưng điều này đã làm: tìm -E. -regex '. * (mp3 | mp4 | exe)'
Joseph Johnson

Giải pháp này sẽ tải các tệp như: mysupermp3.jpgxem xét thêm phần $cuối của regex và \\.trước phần mở rộng
Panthro

1
@Panthro: thực sự, nó sẽ không. Tìm xuất hiện để sử dụng neo ngụ ý. Dấu chấm là một ý tưởng tốt (chỉ cần một dấu gạch chéo ngược).
Tạm dừng cho đến khi có thông báo mới.

38

egrep - grep mở rộng - sẽ giúp ở đây

ls | egrep '\.mp4$|\.mp3$|\.exe$'

nên làm công việc.


Đó là nó! Cảm ơn Chỉ cần nhận ra tôi nên có trường hợp không nhạy cảm, vì vậy tôi đang sử dụng: ls | egrep -i '\ .mp4 $ | \ .mp3 $ | \ .exe $ Bao gồm bất kỳ ai khác cần giúp đỡ trong một ngày. Tôi luôn luôn ngạc nhiên bởi tốc độ tôi nhận được câu trả lời của tôi ở đây.
Mint

Tôi không thể thấy nó sẽ hoạt động như thế nào. ls mà không có tùy chọn nào tạo ra đầu ra trong các cột. Neo đến cuối dòng sẽ không khớp đúng.
camh

4
@camh: lsđến một thiết bị đầu cuối (hoặc có -Ctùy chọn) tạo đầu ra nhiều cột. lsđến một đường ống (hoặc với -1) có đầu ra cột đơn. (So ​​sánh đầu ra của lsvới ls | cat).
mob

Có một dấu nháy đơn bị mất ở cuối. Khác hơn là nó dường như làm việc.
Bjorn

12

cách dễ nhất là chỉ sử dụng ls

ls *.mp4 *.mp3 *.exe

2
Cảm ơn, nhưng tôi đã thử nó và tôi không thích những lỗi bạn gặp phải khi không có tập tin. Bạn có thể sửa nó bằng cách thực hiện: ls * .mp4 * .mp3 * .exe 2> / dev / null Chỉ nghĩ về điều đó ngay bây giờ: P
Mint

1
Tôi ngạc nhiên rằng lskhông có một số tùy chọn im lặng.
MitMaro

2
Trong bash, bạn có thể thực hiện "set -o nullglob" và bạn sẽ không gặp lỗi.
camh

2
Lỗi của tôi - đó phải là "shopt -s nullglob" chứ không phải lệnh set -o
camh

1
Hoặc chỉ sử dụng "echo": echo * .mp4 * .mp3 * .exe
Adrian Pronk

9

Chỉ trong trường hợp: tại sao bạn không sử dụng find?

find -iname '*.mp3' -o -iname '*.exe' -o -iname '*.mp4'

Tôi thấy điều này hoạt động thay thế - find . -name '*.mkv' -o -name '*.flv'(thêm nhiều mệnh đề -o theo yêu cầu). Tôi cần .chỉ ra thư mục và cờ -namekhông -iname- Tôi đang dùng macOS 10.13.
Chris

6

Không cần grep. Shell wildcards sẽ làm các thủ thuật.

ls *.mp4 *.mp3 *.exe

Nếu bạn đã chạy

shopt -s nullglob

sau đó các khối lượng chưa từng có sẽ được loại bỏ hoàn toàn và không bị bỏ lại trên dòng lệnh chưa được mở rộng.

Nếu bạn muốn toàn cầu không phân biệt chữ hoa chữ thường (vì vậy * .mp3 sẽ khớp với foo.MP3):

shopt -s nocaseglob

Nhận xét tương tự như tôi đã đưa cho Good Time Tribe.
Mint

1
Tôi đang cố gắng sử dụng -Rtùy chọn này để liệt kê các tệp phù hợp trong thư mục con nhưng tùy chọn này dường như không có bất kỳ ảnh hưởng nào và tôi vẫn chỉ nhận được kết quả của thư mục hiện tại.
Chris

3

Trong trường hợp bạn vẫn đang tìm kiếm một giải pháp thay thế:

ls | grep -i -e '\\.tcl$' -e '\\.exe$' -e '\\.mp4$'

Vui lòng thêm cờ -e nếu cần.


3

Đối với người dùng OSX :

Nếu bạn sử dụng ls *.{mp3,exe,mp4}, nó sẽ báo lỗi nếu một trong những tiện ích mở rộng đó không có kết quả.

Việc sử dụng ls *.(mp3|exe|mp4)sẽ trả về tất cả các tệp khớp với các tiện ích mở rộng đó, ngay cả khi một trong các tiện ích mở rộng có 0 kết quả .


5
Tôi đã có một lỗi cú pháp bằng cách sử dụng ví dụ của bạn ??? 'bash: lỗi cú pháp gần mã thông báo bất ngờ `('
nagordon

2
Tôi đoán bạn có nghĩa là ls *.@(mp3|exe|mp4). Bạn cần shopt -s extglobcho việc này để làm việc. Nhân tiện, lscũng vô dụng, bạn chỉ có thể làm printf '%s\n' *.@(mp3|exe|mp4).
gniourf_gniourf

1
Tôi nhận được cú pháp tin nhắn mã thông báo bất ngờ trên macOS 10.13
Chris

1
ls | grep "\.mp4$
\.mp3$
\.exe$"

Cảm ơn, nhưng một chút bất tiện khi sử dụng lên vài dòng.
Mint

Điều này + mdfindmang lại các tìm kiếm tốt nhất / nhanh nhất EVER! mdfind -name querystring | grep "\.h$" tìm thấy tất cả các tiêu đề với quesry chuỗi trong tiêu đề tệp. ngay.
Alex Gray

1

ls -R | findstr ".mp3"

ls -R => liệt kê các thư mục con theo cách đệ quy


-1

Đây là một ví dụ làm việc cho tôi.

find <mainfolder path> -name '*myfiles.java' | xargs -n 1 basename
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.