ไวยากรณ์ที่ถูกต้องสำหรับ:
find . -type f -name \*.\(shtml\|css\)
ใช้งานได้ แต่ไม่เหมาะสม:
find . -type f -name \*.shtml > f.txt && find . -type f -name \*.css >> f.txt
วิธีการทำเช่นเดียวกัน แต่ในการกดแป้นพิมพ์น้อยลง?
ไวยากรณ์ที่ถูกต้องสำหรับ:
find . -type f -name \*.\(shtml\|css\)
ใช้งานได้ แต่ไม่เหมาะสม:
find . -type f -name \*.shtml > f.txt && find . -type f -name \*.css >> f.txt
วิธีการทำเช่นเดียวกัน แต่ในการกดแป้นพิมพ์น้อยลง?
คำตอบ:
คุณสามารถรวมนิพจน์การค้นหาต่าง ๆ กับตัวดำเนินการเชิงตรรกะ-or
หรือ-and
เพื่อให้กรณีของคุณสามารถเขียนเป็น
find . -type f \( -name "*.shtml" -or -name "*.css" \)
สิ่งนี้ยังแสดงให้เห็นว่าคุณไม่จำเป็นต้องหลีกเลี่ยงอักขระเชลล์พิเศษเมื่อคุณใช้เครื่องหมายคำพูด
แก้ไข
เนื่องจาก-or
มีลำดับความสำคัญต่ำกว่าโดยนัย-and
ระหว่าง-type
และส่วนแรกของการ-name
ใส่ชื่อลงในวงเล็บตามที่ Chris แนะนำ
). Second, the parentheses need to go around whole ‘primaries’ (the open parenthesis needs to be before
-name ' ไม่ใช่ระหว่างมันกับ' operand ')
นี่เป็นวิธีหนึ่งในการทำเวอร์ชันแรกของคุณ:
find -type f -regex ".*/.*\.\(shtml\|css\)"
คุณต้องใส่เครื่องหมายวงเล็บเพื่อรวมเฉพาะไฟล์:
find . -type f \( -name "*.shtml" -o -name "*.css" \) -print
โบนัส : นี่คือไวยากรณ์ที่สอดคล้องกับ POSIX
ฉันมักจะพบว่าตัวเองจบลงด้วยการใช้ egrep หรือท่อที่ยาวกว่าหรือ perl สำหรับตัวกรองที่ซับซ้อนยิ่งขึ้น:
find . -type f | egrep '\.(shtml|css)$'
find . -type f | perl -lne '/\.shtml|\.css|page\d+\.html$/ and print'
มันอาจจะค่อนข้างมีประสิทธิภาพน้อยกว่า แต่ก็ไม่ได้เป็นข้อกังวลและสำหรับสิ่งที่ซับซ้อนกว่าปกติแล้วมันจะง่ายต่อการสร้างและแก้ไข
คำเตือนมาตรฐานใช้กับการไม่ใช้สิ่งนี้กับไฟล์ที่มีชื่อไฟล์แปลก (เช่นมีการขึ้นบรรทัดใหม่)