bash find xargs grep ปรากฏเพียงครั้งเดียวเท่านั้น


16

อาจจะแปลกไปหน่อยและบางทีอาจมีเครื่องมืออื่นที่จะทำเช่นนี้ แต่ก็ ..

ฉันใช้คำสั่ง bash แบบคลาสสิคต่อไปนี้เพื่อค้นหาไฟล์ทั้งหมดที่มีสตริง:

find . -type f | xargs grep "something"

ฉันมีไฟล์จำนวนมากในหลายระดับ การเกิดขึ้นครั้งแรกของ "บางสิ่ง" นั้นเพียงพอสำหรับฉัน แต่การค้นหายังคงค้นหาอยู่และใช้เวลานานในการทำให้ไฟล์ที่เหลือเสร็จสมบูรณ์ สิ่งที่ฉันต้องการจะทำคือการ "ตอบกลับ" จาก grep back เพื่อค้นหาเพื่อให้การค้นหาสามารถหยุดการค้นหาไฟล์เพิ่มเติมได้ เป็นไปได้ไหม

คำตอบ:


20

เพียงเก็บไว้ในขอบเขตของการค้นหา:

find . -type f -exec grep "something" {} \; -quit

นี่คือวิธีการทำงาน:

-execจะทำงานเมื่อ-type fจะเป็นจริง และเนื่องจากgrepผลตอบแทน0(สำเร็จ / จริง) เมื่อ-exec grep "something"มีการแข่งขันจึง-quitจะถูกเรียก


8
find -type f | xargs grep e | head -1

ไม่ตรงว่าเมื่อheadสิ้นสุดองค์ประกอบกลางของท่อจะได้รับแจ้งมีสัญญาณ 'ท่อหัก' findยุติในการเปิดและแจ้ง คุณควรเห็นการแจ้งเตือนเช่น

xargs: grep: terminated by signal 13

ซึ่งยืนยันสิ่งนี้


+1 สำหรับคำอธิบายและทางเลือกแม้ว่าคำตอบอื่น ๆ จะดูสง่างามกว่าสำหรับฉันเพราะเป็นแบบพอเพียง
hello_earth

8

ทำได้โดยไม่ต้องเปลี่ยนเครื่องมือ: (ฉันชอบ xargs)

#!/bin/bash
find . -type f |
    # xargs -n20 -P20: use 10 parallel processes to grep files in batches of 20
    # grep -m1: show just on match per file
    # grep --line-buffered: multiple matches from independent grep processes
    #      will not be interleaved
    xargs -P10 -n20 grep -m1 --line-buffered "$1" 2> >(
        # Error output (stderr) is redirected to this command.
        # We ignore this particular error, and send any others back to stderr.
        grep -v '^xargs: .*: terminated by signal 13$' >&2
    ) |
    # Little known fact: all `head` does is send signal 13 after n lines.
    head -n 1

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