แสดงรายการไฟล์ที่มีนามสกุลเฉพาะด้วย ls และ grep


153

ฉันต้องการรับไฟล์จาก dir ปัจจุบันและส่งออกเฉพาะ. mp4 ไฟล์. mp3.mp3 เท่านั้น ดังนั้นฉันคิดว่าฉันสามารถทำได้:

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

แต่ไม่เพราะ grep ตัวแรกจะออกมาเพียงแค่ mp4 เท่านั้นส่วนอีก 2 grep จะไม่ถูกใช้งาน

ความคิดใด ๆ PS, รันสคริปต์นี้บน Slow Leopard


1
นี้จริงๆเป็นวิธีที่ผิด - แทนการใช้ grep ใช้แล้วก็หมายถึงshopt -s nullglob *.exe *.mp3 *.mp4ดูmywiki.wooledge.org/ParsingLs
Charles Duffy

1
ฉันไม่สามารถคิดออกหรือไม่ "เสือดาวช้า" เป็นคำสะกดผิด ...
Wowfunhappy

1
@ Wowfunhappy ฮ่าฮ่าฮ่าเป็นตัวพิมพ์ผิดแน่นอนฉันจำได้ว่า Snow Leopard นั้นค่อนข้างเร็ว
มิ้นต์

คำตอบ:


336

ทำไมจะไม่ล่ะ:

ls *.{mp3,exe,mp4}

ฉันไม่แน่ใจว่าฉันเรียนที่ไหน - แต่ฉันใช้สิ่งนี้


1
สิ่งนี้ไม่ทำงานสำหรับฉันเนื่องจากส่วนขยายที่ฉันใช้นั้นใช้สำหรับไดเรกทอรีดังนั้น ls จึงแสดงรายการเนื้อหาของไดเรกทอรี
Richard Venable

1
@RichardVenable เพิ่มสวิตช์ -d เพื่อป้องกันไม่ให้ไดเรกทอรีซ้ำ
Carlos Eugenio Thompson Pinzón

11
ฉันชอบโซลูชันนี้ แต่ดูเหมือนว่าจะล้มเหลวหากคุณขาดไฟล์ประเภทใดประเภทหนึ่ง ตัวอย่างเช่นคุณมี mp3 แต่ไม่มี. exe (Mac OSX, zsh)
JHo

2
ฉันเปลี่ยนเส้นทาง stderr ไปที่ / dev / null เพื่อหลีกเลี่ยงls: *.exe: No such file or directoryเช่น:ls *.{zip,tar.gz,tar} 2>/dev/null
Isaac

1
เมื่อฉันรัน ls foo *. {tar.gz, zip} โดยตรงในเชลล์มันทำงานได้ แต่เมื่อวางไว้ใน shell script ล่าสุด = $ (ls -I ' .done' -tr $ {pkgprefix} . {tar gz, zip} | tail -1) ฉันได้รับข้อความแสดงข้อผิดพลาด: ls: ไม่สามารถเข้าถึง 'bamtools *. {tar.gz, zip}': ไม่มีไฟล์หรือไดเรกทอรีดังกล่าวคนที่ฉลาดกว่าสามารถกลั่นกรองคำตอบได้
Kemin Zhou

41

ใช้นิพจน์ทั่วไปด้วยfind:

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

หากคุณกำลังวางชื่อไฟล์:

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

วิธีนี้จะป้องกันชื่อไฟล์ที่มีช่องว่างหรือขึ้นบรรทัดใหม่

OS X findรองรับการสลับกันเฉพาะเมื่อใช้-Eตัวเลือก (ขั้นสูง)

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

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

3
และนั่นไม่ได้ผลสำหรับฉันบน mac os แต่สิ่งนี้ทำได้: ค้นหา -E -regex '. * (mp3 | mp4 | exe)'
Joseph Johnson

วิธีการแก้ปัญหานี้จะโหลดไฟล์เช่น: mysupermp3.jpgพิจารณาการเพิ่ม$ในตอนท้ายของ regex และ\\.ก่อนส่วนขยาย
Panthro

1
@Panthro: จริง ๆ แล้วมันจะไม่ ค้นหาดูเหมือนจะใช้จุดยึดโดยนัย จุดเป็นความคิดที่ดี (จำเป็นต้องใช้แบ็กสแลชเดียวเท่านั้น)
หยุดชั่วคราวจนกว่าจะมีการแจ้งให้ทราบต่อไป

39

egrep - grep เพิ่มเติม - จะช่วยเหลือที่นี่

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

ควรทำงาน


แค่นั้นแหละ! ขอบคุณเพิ่งรู้ว่าฉันควรจะมีกรณีตายดังนั้นฉันใช้: ls | egrep -i '\ .mp4 $ | \ .mp3 $ | \ .exe $ หากผู้อื่นต้องการความช่วยเหลือในหนึ่งวัน ฉันประหลาดใจเสมอกับความเร็วที่ฉันได้รับคำตอบจากที่นี่
มิ้นต์

ฉันไม่เห็นว่ามันจะทำงานอย่างไร ls โดยไม่มีตัวเลือกใด ๆ ที่สร้างผลลัพธ์ในคอลัมน์ การยึดกับส่วนท้ายของบรรทัดจะไม่ตรงกัน
camh

4
@camh: lsไปยังเทอร์มินัล (หรือด้วย-Cตัวเลือก) สร้างเอาต์พุตหลายคอลัมน์ lsไปยังไปป์ (หรือด้วย-1) มีเอาต์พุตคอลัมน์เดี่ยว (เปรียบเทียบผลลัพธ์จากlsกับls | cat)
ม็อบ

ท้ายที่สุดแล้วอะพอสโทรฟีก็หายไป นอกเหนือจากที่ดูเหมือนว่าจะทำงาน
Björn

12

วิธีที่ง่ายที่สุดคือใช้ ls

ls *.mp4 *.mp3 *.exe

2
ขอบคุณ แต่ฉันลองแล้วและฉันไม่ชอบข้อผิดพลาดที่คุณได้รับเมื่อไม่มีไฟล์ คุณฉันสามารถแก้ไขได้โดยทำ: ls * .mp4 * .mp3 * .exe 2> / dev / null คิดเพียงว่าตอนนี้เจ้า: P
มิ้นต์

1
ฉันประหลาดใจที่lsไม่มีตัวเลือกเงียบ ๆ
MitMaro

2
ในทุบตีคุณสามารถทำ "set -o nullglob" และคุณจะไม่ได้รับข้อผิดพลาด
camh

2
ความผิดพลาดของฉัน - ที่ควรจะเป็น "shopt -s nullglob" ไม่ได้ตั้งค่า -o คำสั่ง
camh

1
หรือเพียงแค่ใช้ "echo": echo * .mp4 * .mp3 * .exe
Adrian Pronk

9

ในกรณีที่: ทำไมคุณไม่ใช้find?

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

ฉันพบว่ามันใช้งานได้แทน - find . -name '*.mkv' -o -name '*.flv'(เพิ่มคำสั่ง -o ได้มากเท่าที่ต้องการ) ฉันต้องการ.เพื่อระบุไดเรกทอรีและค่าสถานะ-nameไม่ใช่-iname- ฉันใช้ macOS 10.13
คริส

6

ไม่จำเป็นต้องใช้ grep สัญลักษณ์ตัวแทนของเชลล์จะใช้เคล็ดลับ

ls *.mp4 *.mp3 *.exe

หากคุณได้วิ่ง

shopt -s nullglob

จากนั้น globs ที่ไม่ตรงกันจะถูกลบออกโดยสิ้นเชิงและไม่ถูกทิ้งไว้ในบรรทัดคำสั่งที่ไม่ขยาย

หากคุณต้องการการเว้นขนาดตัวพิมพ์เล็กและตัวพิมพ์ใหญ่ (ดังนั้น * .mp3 จะจับคู่ foo.MP3):

shopt -s nocaseglob

ความคิดเห็นแบบเดียวกับที่ฉันให้กับ Good Time Tribe
มิ้นต์

1
ฉันกำลังพยายามใช้สิ่งนี้พร้อม-Rตัวเลือกเพื่อแสดงรายการไฟล์ที่ตรงกันในไดเรกทอรีย่อย แต่ตัวเลือกดูเหมือนจะไม่มีผลใด ๆ และฉันก็ยังได้รับผลลัพธ์ของไดเรกทอรีปัจจุบันเท่านั้น
คริส

3

ในกรณีที่คุณยังคงมองหาวิธีการอื่น:

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

อย่าลังเลที่จะเพิ่มแฟล็ก -e เพิ่มเติมหากจำเป็น


3

สำหรับผู้ใช้ OSX :

ถ้าคุณใช้ls *.{mp3,exe,mp4}, มันจะโยนความผิดพลาดถ้าหนึ่งในส่วนขยายเหล่านี้ไม่มีผล

การใช้ls *.(mp3|exe|mp4)จะส่งคืนไฟล์ทั้งหมดที่ตรงกับส่วนขยายเหล่านั้นแม้ว่าหนึ่งในส่วนขยายจะมีผลลัพธ์ 0รายการ


5
ฉันพบข้อผิดพลาดทางไวยากรณ์โดยใช้ตัวอย่างของคุณ ??? 'bash: ข้อผิดพลาดทางไวยากรณ์ใกล้โทเค็นที่ไม่คาดคิด `('
nagordon

2
ls *.@(mp3|exe|mp4)ผมคิดว่าคุณหมายถึง คุณต้องการshopt -s extglobสิ่งนี้ในการทำงาน โดยวิธีการที่จะไม่ได้ผลมากเกินไปคุณก็สามารถทำได้ls printf '%s\n' *.@(mp3|exe|mp4)
gniourf_gniourf

1
ฉันได้รับข้อความโทเค็นข้อความที่ไม่คาดคิดใน macOS 10.13
Chris

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

ขอขอบคุณ แต่ใช้งานไม่สะดวกหลายสาย
มิ้นต์

+ นี้mdfindให้ผลการค้นหาที่ดีที่สุด / เร็วที่สุดที่เคยมีมา! mdfind -name querystring | grep "\.h$" ค้นหาส่วนหัวทั้งหมดที่มี quesrystring ในชื่อไฟล์ อย่างทันทีทันใด
Alex Gray


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.