ค้นหาไฟล์ที่กรองโดยหลายนามสกุล


52

ไวยากรณ์ที่ถูกต้องสำหรับ:

find . -type f -name \*.\(shtml\|css\)

ใช้งานได้ แต่ไม่เหมาะสม:

find . -type f -name \*.shtml > f.txt && find . -type f -name \*.css >> f.txt

วิธีการทำเช่นเดียวกัน แต่ในการกดแป้นพิมพ์น้อยลง?

คำตอบ:


75

คุณสามารถรวมนิพจน์การค้นหาต่าง ๆ กับตัวดำเนินการเชิงตรรกะ-orหรือ-andเพื่อให้กรณีของคุณสามารถเขียนเป็น

find . -type f \( -name "*.shtml" -or -name "*.css" \)

สิ่งนี้ยังแสดงให้เห็นว่าคุณไม่จำเป็นต้องหลีกเลี่ยงอักขระเชลล์พิเศษเมื่อคุณใช้เครื่องหมายคำพูด

แก้ไข

เนื่องจาก-orมีลำดับความสำคัญต่ำกว่าโดยนัย-andระหว่าง-typeและส่วนแรกของการ-nameใส่ชื่อลงในวงเล็บตามที่ Chris แนะนำ


ซึ่งจะพิมพ์ไดเรกทอรีชื่อ "* .css" ด้วย
ตุ๊กตา

อืมวงเล็บในรุ่นที่อัปเดตของคุณนั้นหายไปเล็กน้อย วงเล็บแต่ละอันจะต้องจบลงด้วยการหาพารามิเตอร์แยกกันดังนั้นพวกเขาจึงต้องการช่องว่างรอบตัวพวกเขา (`" .css ")` ผลลัพธ์ในค่าสตริงเดียว มันเป็นเช่นเดียวกับ (เช่น) `' .css)' ). Second, the parentheses need to go around whole ‘primaries’ (the open parenthesis needs to be before -name ' ไม่ใช่ระหว่างมันกับ' operand ')
Chris Johnsen


12

คุณต้องใส่เครื่องหมายวงเล็บเพื่อรวมเฉพาะไฟล์:

find . -type f \( -name "*.shtml" -o -name "*.css" \) -print

โบนัส : นี่คือไวยากรณ์ที่สอดคล้องกับ POSIX


4

ฉันมักจะพบว่าตัวเองจบลงด้วยการใช้ egrep หรือท่อที่ยาวกว่าหรือ perl สำหรับตัวกรองที่ซับซ้อนยิ่งขึ้น:

find . -type f | egrep '\.(shtml|css)$'
find . -type f | perl -lne '/\.shtml|\.css|page\d+\.html$/ and print'

มันอาจจะค่อนข้างมีประสิทธิภาพน้อยกว่า แต่ก็ไม่ได้เป็นข้อกังวลและสำหรับสิ่งที่ซับซ้อนกว่าปกติแล้วมันจะง่ายต่อการสร้างและแก้ไข

คำเตือนมาตรฐานใช้กับการไม่ใช้สิ่งนี้กับไฟล์ที่มีชื่อไฟล์แปลก (เช่นมีการขึ้นบรรทัดใหม่)


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