สมมติว่าอาจมี*.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"