Daftar file dengan ekstensi tertentu dengan ls dan grep


153

Saya hanya ingin mendapatkan file dari direktori saat ini dan hanya mengeluarkan file .mp4 .mp3 .exe. Jadi saya pikir saya bisa melakukan ini:

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

Tapi tidak, karena grep pertama akan menampilkan hanya mp4 maka 2 grep lainnya tidak akan digunakan.

Ada ide? PS, Menjalankan skrip ini di Slow Leopard.


1
Ini benar-benar pendekatan yang salah - daripada menggunakan grep, gunakan shopt -s nullglobdan kemudian hanya merujuk *.exe *.mp3 *.mp4. Lihat mywiki.wooledge.org/ParsingLs
Charles Duffy

1
Saya tidak tahu apakah "Slow Leopard" itu salah ketik ...
Wowfunhappy

1
@Wowfunhappy hahaha, pasti salah ketik, saya ingat berpikir Snow Leopard cukup cepat.
Mint

Jawaban:


336

Kenapa tidak:

ls *.{mp3,exe,mp4}

Saya tidak yakin dari mana saya mempelajarinya - tetapi saya telah menggunakan ini.


1
Ini tidak berfungsi untuk saya karena ekstensi yang saya gunakan adalah untuk direktori, jadi ls adalah daftar isi direktori.
Richard Venable

1
@RichardVenable menambahkan saklar -d untuk mencegah direktori terulang.
Carlos Eugenio Thompson Pinzón

11
Saya suka solusi ini tetapi tampaknya gagal jika Anda kehilangan salah satu tipe file. Misalnya, Anda memiliki mp3 tetapi tidak ada .exe (Mac OSX, zsh)
JHo

2
Saya mengarahkan stderr ke / dev / null untuk menghindari ls: *.exe: No such file or directorymis:ls *.{zip,tar.gz,tar} 2>/dev/null
Isaac

1
Ketika saya menjalankan ls foo *. {Tar.gz, zip} langsung di shell berfungsi, tetapi ketika menempatkan ini di dalam skrip shell terbaru = $ (ls -I ' .done' -tr $ {pkgprefix} . {Tar. gz, zip} | tail -1) Saya mendapat pesan kesalahan: ls: tidak dapat mengakses 'bamtools *. {tar.gz, zip}': Tidak ada file atau direktori seperti itu, siapa pun yang lebih pintar dapat memperbaiki jawabannya.
Kemin Zhou

41

Gunakan ekspresi reguler dengan find:

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

Jika Anda memipipkan nama file:

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

Ini melindungi nama file yang mengandung spasi atau baris baru.

OS X findhanya mendukung pergantian ketika opsi -E(ditingkatkan) digunakan.

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

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

3
andi, itu tidak berhasil untuk saya di mac os. Tapi ini berhasil: find -E. -regex '. * (mp3 | mp4 | exe)'
Joseph Johnson

Solusi ini akan memuat file seperti: mysupermp3.jpgpertimbangkan untuk menambahkan $di akhir regex dan \\.sebelum ekstensi
Panthro

1
@Panthro: sebenarnya, tidak akan. Cari tampaknya menggunakan jangkar tersirat. Titik adalah ide yang bagus (hanya satu garis miring terbalik yang diperlukan).
Dijeda sampai pemberitahuan lebih lanjut.

39

egrep - grep yang diperluas - akan membantu di sini

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

harus melakukan pekerjaan.


Itu dia! Terima kasih Baru sadar saya seharusnya tidak sensitif huruf, jadi saya menggunakan: ls | egrep -i '\ .mp4 $ | \ .mp3 $ | \ .exe $ Memetikan orang lain yang membutuhkan bantuan dengan itu suatu hari. Saya selalu terkejut dengan kecepatan saya mendapatkan jawaban saya di sini.
Mint

Saya tidak bisa melihat bagaimana ini akan bekerja. ls tanpa opsi menghasilkan output dalam kolom. Menambatkan ke ujung garis tidak akan cocok dengan benar.
camh

4
@camh: lske terminal (atau dengan -Copsi) menghasilkan output multi-kolom. lske pipa (atau dengan -1) memiliki output kolom tunggal. (Bandingkan keluaran lsdengan ls | cat).
mob

Ada tanda kutip yang hilang di akhir. Selain itu tampaknya berhasil.
Björn

12

cara termudah adalah dengan menggunakan ls

ls *.mp4 *.mp3 *.exe

2
Terima kasih, tapi saya sudah mencobanya dan saya tidak suka kesalahan yang Anda dapatkan ketika tidak ada file. Engkau dapat memperbaikinya dengan melakukan: ls * .mp4 * .mp3 * .exe 2> / dev / null Hanya memikirkannya sekarang: P
Mint

1
Saya terkejut karena lstidak memiliki opsi diam.
MitMaro

2
Dalam bash, Anda dapat melakukan "set -o nullglob", dan Anda tidak akan mendapatkan kesalahan.
camh

2
Kesalahan saya - itu seharusnya "shopt -s nullglob" bukan perintah set -o
camh

1
Atau cukup gunakan "echo": echo * .mp4 * .mp3 * .exe
Adrian Pronk

9

Untuk jaga-jaga: mengapa Anda tidak menggunakannya find?

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

Saya menemukan ini bekerja sebagai gantinya - find . -name '*.mkv' -o -name '*.flv'(menambahkan klausa -o sebanyak yang diperlukan). Saya membutuhkan .untuk menunjukkan direktori dan bendera -nametidak -iname- saya di macOS 10.13.
Chris

6

Tidak perlu grep. Shell wildcard akan melakukan triknya.

ls *.mp4 *.mp3 *.exe

Jika sudah lari

shopt -s nullglob

maka gumpalan yang tak tertandingi akan dihapus sama sekali dan tidak dibiarkan di baris perintah tanpa ekspansi.

Jika Anda ingin globbing case-insensitive (jadi * .mp3 akan cocok dengan foo.MP3):

shopt -s nocaseglob

Komentar yang sama seperti yang saya berikan kepada Good Time Tribe.
Mint

1
Saya mencoba menggunakan ini dengan -Ropsi untuk daftar file yang cocok di subdirektori tetapi opsi tampaknya tidak berpengaruh dan saya masih hanya mendapatkan hasil direktori saat ini.
Chris

3

Jika Anda masih mencari solusi alternatif:

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

Jangan ragu untuk menambahkan lebih banyak flag -e jika diperlukan.


3

Untuk pengguna OSX :

Jika Anda menggunakan ls *.{mp3,exe,mp4}, itu akan menimbulkan kesalahan jika salah satu ekstensi tersebut tidak memiliki hasil.

Menggunakan ls *.(mp3|exe|mp4)akan mengembalikan semua file yang cocok dengan ekstensi itu, bahkan jika salah satu ekstensi memiliki hasil 0 .


5
Saya mendapat kesalahan sintaksis menggunakan contoh Anda ??? 'bash: kesalahan sintaks dekat token yang tidak terduga `('
nagordon

2
Saya kira maksud Anda ls *.@(mp3|exe|mp4). Anda perlu shopt -s extglobini untuk bekerja. Ngomong-ngomong, lstidak berguna juga, Anda bisa melakukannya printf '%s\n' *.@(mp3|exe|mp4).
gniourf_gniourf

1
Saya mendapatkan pesan token sintaks yang tidak terduga di macOS 10.13
Chris

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

Terima kasih, tetapi sedikit merepotkan menggunakan beberapa baris.
Mint

Ini + mdfindmenghasilkan pencarian terbaik / tercepat yang pernah ada! mdfind -name querystring | grep "\.h$" menemukan semua header dengan quesrystring dalam judul file. pronto.
Alex Grey

1

ls -R | findstr ".mp3"

ls -R => daftar subdirektori secara rekursif


-1

Ini adalah satu contoh yang cocok untuk saya.

find <mainfolder path> -name '*myfiles.java' | xargs -n 1 basename
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.