วิธีใช้ regex พร้อมคำสั่ง find?


297

ฉันมีภาพบางภาพที่มีชื่อด้วยสตริง uuid1 ที่สร้างขึ้น ตัวอย่างเช่น 81397018-b84a-11e0-9d2a-001b77dc0bed.jpg ฉันต้องการค้นหาภาพเหล่านี้ทั้งหมดโดยใช้คำสั่ง "find":

find . -regex "[a-f0-9\-]\{36\}\.jpg".

แต่มันไม่ทำงาน มีอะไรผิดปกติกับ regex หรือไม่ มีคนช่วยฉันได้ไหม


7
อาจเปลี่ยน regextype ค่าเริ่มต้นคือEmacs Regular Expressionไม่ว่าสิ่งนั้นจะหมายถึงอะไร
pavium

คำตอบ:


348
find . -regextype sed -regex ".*/[a-f0-9\-]\{36\}\.jpg"

โปรดทราบว่าคุณต้องระบุ.*/ในจุดเริ่มต้นเนื่องจากfindตรงกับเส้นทางทั้งหมด

ตัวอย่าง:

susam@nifty:~/so$ find . -name "*.jpg"
./foo-111.jpg
./test/81397018-b84a-11e0-9d2a-001b77dc0bed.jpg
./81397018-b84a-11e0-9d2a-001b77dc0bed.jpg
susam@nifty:~/so$ 
susam@nifty:~/so$ find . -regextype sed -regex ".*/[a-f0-9\-]\{36\}\.jpg"
./test/81397018-b84a-11e0-9d2a-001b77dc0bed.jpg
./81397018-b84a-11e0-9d2a-001b77dc0bed.jpg

รุ่นที่ฉันค้นหา:

$ find --version
find (GNU findutils) 4.4.2
Copyright (C) 2007 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by Eric B. Decker, James Youngman, and Kevin Dalley.
Built using GNU gnulib version e5573b1bad88bfabcda181b9e0125fb0c52b7d3b
Features enabled: D_TYPE O_NOFOLLOW(enabled) LEAF_OPTIMISATION FTS() CBO(level=0) 
susam@nifty:~/so$ 
susam@nifty:~/so$ find . -regextype foo -regex ".*/[a-f0-9\-]\{36\}\.jpg"
find: Unknown regular expression type `foo'; valid types are `findutils-default', `awk', `egrep', `ed', `emacs', `gnu-awk', `grep', `posix-awk', `posix-basic', `posix-egrep', `posix-extended', `posix-minimal-basic', `sed'.

4
@Tom มันเป็นวิธีที่ regex ในการค้นหางาน จากหน้า man นั้น regex ตรงกับพา ธ ไฟล์ทั้งหมดรวมไดเรกทอรีซึ่งหมายความว่ามีนัยโดย"^ ... $"รอบ regex ของคุณ จะต้องตรงกับบรรทัดผลลัพธ์ทั้งหมด
Manny D

2
ฉันไม่คิดว่าคุณต้องการสิ่งต่อไปนี้เพราะจับคู่อักขระใดก็ได้/ในศูนย์เกือบ (หรือมากกว่า) .*/.*
Jeff

2
สำหรับผู้ที่ (เช่นฉัน) ที่ไม่ได้อ่าน regex อย่างถูกต้องในครั้งแรก: สังเกตแบ็กสแลชที่นำหน้าอักขระพิเศษ regex เช่น:\{36\}
Lucas Wilson-Richter

11
ฉันมีปัญหาในการค้นหารายการ regex เต็มรูปแบบ (manpage ไม่ทันสมัย):valid types are 'findutils-default', 'awk', ' egrep', 'ed', 'emacs', 'gnu-awk', 'grep', 'posix-awk', 'posix-basic', 'posix-egrep', 'posix -extended', 'posix-minimal-basic', 'sed'.
Noah Sussman

4
ตรวจสอบให้แน่ใจที่จะนำ-regextypeธงก่อน-regexธงมิฉะนั้นมันใช้ไม่ได้!
Christopher Orr

84

-regexแสดงออกพบตรงกับชื่อทั้งหมดรวมทั้งญาติเส้นทางจากไดเรกทอรีปัจจุบัน สำหรับfind .สิ่งนี้เริ่มต้นด้วยเสมอ./จากนั้นไดเรกทอรีใด ๆ

นอกจากนี้เหล่านี้ยังemacsเป็นนิพจน์ทั่วไปซึ่งมีกฎการหลบหนีอื่นที่ไม่ใช่นิพจน์ทั่วไปเช่นเรปทั่วไป

หากสิ่งเหล่านี้ทั้งหมดโดยตรงในไดเรกทอรีปัจจุบันแล้ว

find . -regex '\./[a-f0-9\-]\{36\}\.jpg'

ควรทำงาน. (ฉันไม่แน่ใจจริงๆ - ฉันไม่สามารถได้รับการนับซ้ำเพื่อทำงานที่นี่) คุณสามารถเปลี่ยนไปใช้การแสดงผล egrep โดย-regextype posix-egrep:

find . -regextype posix-egrep -regex '\./[a-f0-9\-]{36}\.jpg'

(โปรดทราบว่าทุกสิ่งที่กล่าวถึงที่นี่มีไว้สำหรับ GNU ฉันไม่ทราบอะไรเกี่ยวกับ BSD ซึ่งเป็นค่าเริ่มต้นบน Mac)


1
ฉันมีวงเล็บสำหรับสตริงการจับคู่หลายรายการใน regex ของฉันดังนั้นposix-egrepรูปแบบที่เหมาะกับฉัน
palswim

2
บางสิ่งบางอย่างที่จะต้องทราบ-regextypeเป็นตัวเลือกสำหรับ GNU findและไม่ BSD (อย่างน้อยไม่ Mac BSD findเหมือน) หากตัวเลือกนี้ไม่สามารถใช้งานได้โปรดติดตั้ง GNU find หากอยู่ใน Mac findutilsที่เป็นไปได้กับแพคเกจชง gfindค้นหาแล้วสามารถใช้ได้ผ่านทาง
DanCat

regextype posix-egrep ทำหน้าที่ให้ฉัน ฉันคิดว่าค่าเริ่มต้นคือ regextype emacs
infoclogged

35

ตัดสินจากคำตอบอื่น ๆ ดูเหมือนว่านี่อาจเป็นความผิดของการค้นหา

อย่างไรก็ตามคุณสามารถทำได้ด้วยวิธีนี้แทน:

find . * | grep -P "[a-f0-9\-]{36}\.jpg"

คุณอาจต้องปรับแต่ง grep เล็กน้อยและใช้ตัวเลือกที่แตกต่างกันขึ้นอยู่กับสิ่งที่คุณต้องการ แต่ใช้งานได้


ทำงานได้ดีสำหรับฉันและให้ระดับที่ยอดเยี่ยมของเสรีภาพกับ regex
glaucon

3
ข้อเสียกับเรื่องนี้คือคุณไม่สามารถใช้ประโยชน์จากfindของ-pruneการทำงานซึ่งจะข้ามไดเรกทอรีบางอย่างสิ้นเชิง บ่อยครั้งที่สิ่งนี้ไม่สำคัญจริงๆ แต่ควรพูดถึง
Alexander Bird

-prune จะยังคงใช้งานได้ฉันเดา มันจะเป็นอันตรายมากกว่าที่จะใช้ -exec - มันจะทำงานกับไฟล์ทั้งหมดและไม่ใช่เฉพาะไฟล์ที่ grep อนุญาตให้ส่งผ่าน
tpb261

13

บน Mac OS X (ค้นหา BSD) : เช่นเดียวกับคำตอบที่ยอมรับ.*/จำเป็นต้องใช้คำนำหน้าเพื่อให้ตรงกับเส้นทางที่สมบูรณ์:

$ find -E . -regex ".*/[a-f0-9\-]{36}.jpg"

man findพูดว่า-Eใช้การสนับสนุนแบบขยาย regex


Seems -Eไม่พร้อมใช้งานบน Ubuntu (ทดสอบบน WSL Ubuntu)
Warlike Chimpanzee

2
@Clever Little Monkey - ไม่คำตอบที่ได้รับการยอมรับควรใช้กับ Ubuntu รูปแบบนี้สำหรับ Mac OS X โดยเฉพาะ (หรืออาจเป็นรูปแบบ BSD อื่นเช่น FreeBSD)
Stan Kurdziel

8

ลองใช้อัญประกาศเดี่ยว (') เพื่อหลีกเลี่ยงการหลบหนีของสตริง โปรดจำไว้ว่านิพจน์ต้องตรงกับเส้นทางทั้งหมดเช่นต้องมีลักษณะดังนี้:

 find . -regex '\./[a-f0-9-]*.jpg'

นอกเหนือจากนั้นดูเหมือนว่าการค้นหาของฉัน (GNU 4.4.2) จะรู้เฉพาะการแสดงออกปกติพื้นฐานโดยเฉพาะอย่างยิ่งไม่ใช่ไวยากรณ์ {36} ฉันคิดว่าคุณจะต้องทำโดยปราศจากมัน


8

วิธีง่ายๆ - คุณสามารถระบุ. * ในจุดเริ่มต้นเพราะค้นหาตรงกับเส้นทางทั้งหมด

$ find . -regextype egrep -regex '.*[a-f0-9\-]{36}\.jpg$'

ค้นหารุ่น

$ find --version
find (GNU findutils) 4.6.0
Copyright (C) 2015 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later 
<http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by Eric B. Decker, James Youngman, and Kevin Dalley.
Features enabled: D_TYPE O_NOFOLLOW(enabled) LEAF_OPTIMISATION 
FTS(FTS_CWDFD) CBO(level=2)

6

คุณควรใช้พา ธ ไดเร็กทอรีสัมบูรณ์เมื่อใช้คำสั่ง find กับนิพจน์ทั่วไป ในตัวอย่างของคุณ

find . -regex "[a-f0-9\-]\{36\}\.jpg"

ควรเปลี่ยนเป็น

find . -regex "./[a-f0-9\-]\{36\}\.jpg"

ในระบบลีนุกซ์ส่วนใหญ่ระบบบางระบบที่ไม่สามารถรับรู้ได้จึงต้องมีการระบุถึง - regexty เช่น

find . -regextype posix-extended -regex "[a-f0-9\-]\{36\}\.jpg"
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.