สมมติว่าอาจมี*.txt
ไฟล์หลายร้อยไฟล์ในไดเรกทอรี ฉันต้องการค้นหา*.txt
ไฟล์สามไฟล์แรกเท่านั้นจากนั้นออกจากกระบวนการค้นหา
วิธีการบรรลุสิ่งนี้โดยใช้find
ยูทิลิตี้? ฉันผ่านไปอย่างรวดเร็วบนหน้าเพจของมันดูเหมือนจะไม่มีตัวเลือกสำหรับสิ่งนี้
สมมติว่าอาจมี*.txt
ไฟล์หลายร้อยไฟล์ในไดเรกทอรี ฉันต้องการค้นหา*.txt
ไฟล์สามไฟล์แรกเท่านั้นจากนั้นออกจากกระบวนการค้นหา
วิธีการบรรลุสิ่งนี้โดยใช้find
ยูทิลิตี้? ฉันผ่านไปอย่างรวดเร็วบนหน้าเพจของมันดูเหมือนจะไม่มีตัวเลือกสำหรับสิ่งนี้
คำตอบ:
คุณสามารถไพพ์เอาต์พุตของfind
ถึงhead
:
find . -name '*.txt' | head -n 3
head
เริ่มต้นขึ้นและรอการป้อนข้อมูลจากด้านซ้ายของท่อ จากนั้นfind
เริ่มต้นขึ้นและค้นหาไฟล์ที่ตรงกับเกณฑ์ที่ระบุส่งเอาต์พุตผ่านไพพ์ เมื่อhead
ได้รับและพิมพ์จำนวนบรรทัดที่ร้องขอมันจะยุติลงและปิดไปป์ find
สังเกตเห็นท่อปิดและมันก็จะยุติลง เรียบง่ายสง่างามและมีประสิทธิภาพ
-n 3
เป็นPOSIX เข้ากันได้และดังนั้นจึงมีแนวโน้มที่จะพกพามากขึ้น
คำตอบอื่น ๆนี้มีข้อบกพร่องค่อนข้าง คำสั่งคือ
find . -name '*.txt' | head -n 3
จากนั้นก็มีคำอธิบายในความคิดเห็นอย่างใดอย่างหนึ่ง [highlight mine]:
head
เริ่มต้นขึ้นและรอการป้อนข้อมูลจากด้านซ้ายของท่อ จากนั้นfind
เริ่มต้นขึ้นและค้นหาไฟล์ที่ตรงกับเกณฑ์ที่ระบุส่งเอาต์พุตผ่านไพพ์ เมื่อhead
ได้รับและพิมพ์จำนวนบรรทัดที่ร้องขอมันจะยุติลงและปิดไปป์find
สังเกตเห็นท่อปิดและมันก็จะยุติลง ที่เรียบง่ายสง่างามและมีประสิทธิภาพ
นี่เป็นเรื่องจริงเกือบ
ปัญหาคือfind
แจ้งไปป์ที่ปิดเฉพาะเมื่อพยายามเขียนถึงมัน - ในกรณีนี้คือเมื่อพบการจับคู่ที่ 4 แต่ถ้าไม่มีแมตช์ที่ 4 ก็find
จะดำเนินต่อไป เปลือกของคุณจะรอ! หากเกิดขึ้นในสคริปต์สคริปต์จะรอแม้ว่าเราจะทราบแล้วว่าการส่งออกไปป์นั้นเป็นที่สิ้นสุดและไม่มีสิ่งใดสามารถเพิ่มเข้าไปได้ ไม่มีประสิทธิภาพ
เอฟเฟกต์นั้นเล็กน้อยถ้าfind
เสร็จสิ้นอย่างรวดเร็วด้วยตัวเอง แต่ด้วยการค้นหาที่ซับซ้อนในต้นไม้ไฟล์ขนาดใหญ่คำสั่งอาจล่าช้าโดยไม่จำเป็นสิ่งที่คุณต้องการที่จะทำต่อไป
วิธีแก้ปัญหาที่ไม่สมบูรณ์แบบคือการใช้งาน
( find … & ) | head -n 3
วิธีนี้เมื่อhead
ออกจากเชลล์จะดำเนินการต่อในทันที find
กระบวนการพื้นหลังอาจถูกละเว้นแล้ว (จะออกไม่ช้าก็เร็ว) หรือกำหนดเป้าหมายด้วยpkill
หรือบางสิ่งบางอย่าง
/
เพื่อพิสูจน์แนวคิดที่คุณอาจค้นหา เราคาดว่าจะมีเพียงนัดเดียว แต่find
มองหาได้ทุกที่และอาจต้องใช้เวลานาน
find / -wholename / 2>/dev/null | head -n 1
ยุติด้วยCtrl+ Cทันทีที่คุณเห็นปัญหา ตอนนี้เปรียบเทียบ:
pidof find ; ( find / -wholename / 2>/dev/null & ) | head -n 1 ; pidof find
find . -name '*.txt' -print -quit
แสดงการแข่งขันนัดแรกเท่านั้นและให้find
ออกหลังจากการแข่งขันครั้งแรก ฉันไม่ทราบว่าเป็นไปได้หรือไม่ที่จะปรับให้เข้ากับกรณี "ทางออกหลังจากค้นหาการจับคู่ n"