ฉันจะ grep ผลลัพธ์ของ FIND โดยใช้ -EXEC และยังส่งออกไปยังไฟล์ได้อย่างไร?


64

ดีกว่าที่จะอธิบายในตัวอย่าง

ฉันสามารถ:

find . -name "*.py" -type f > output.txt

แต่ฉันจะเก็บเอาท์พุทเป็นไฟล์เดียวกันได้อย่างไร:

find . -name "*.py" -type f -exec grep "something" {} \

ฉันไม่สามารถทำได้

find . -name "*.py" -type f -exec grep "something" {} \ > output.txt

คำตอบ:


105

ถ้าฉันเข้าใจคุณอย่างถูกต้องนี่คือสิ่งที่คุณต้องการทำ:

find . -name '*.py' -print0 | xargs -0 grep 'something' > output.txt

Findไฟล์ทั้งหมดที่มีนามสกุลpy, grepเฉพาะแถวที่มีและบันทึกแถวในsomething output.txtหากไฟล์มีสิ่งใดไฟล์จะถูกแทนที่

แก้ไข: การใช้ -exec:

find . -name '*.py' -exec grep 'something' {} \; > output.txt

ฉันกำลังรวมความคิดเห็นของ Chris Downs ไว้ที่นี่ คำสั่งดังกล่าวจะส่งผลให้grepมีการดำเนินการหลายครั้งเท่าที่findพบว่าเกิดขึ้น แต่ถ้าคุณแทนที่;ด้วย+, grepเรียกว่ามีการส่งออกจากfindการตัดแบ่ง (ถึงขีด จำกัด บางอย่าง) ดูคำถามการใช้เครื่องหมายอัฒภาค (;) vs plus (+) กับ exec ในการค้นหาเพิ่มเติมเกี่ยวกับเรื่อง


16
ใช้+แทน\;มันจะปรับปรุงเวลาดำเนินการอย่างมีนัยสำคัญ (เนื่องจากมันจะขัดแย้งกับข้อโต้แย้งก่อนที่จะดำเนินการจนถึงARG_MAX)
Chris Down

ตอนนี้ฉันเข้าใจพลังของ xargs! ขอบคุณ!
domih

4
ใช้grep -Hหากคุณต้องการรวมชื่อไฟล์ของไฟล์ในเอาต์พุต
Steinar

18

หากคุณต้องการบันทึกบรรทัดที่ตรงกันทั้งหมดในไฟล์ทั้งหมดoutput.txtคำสั่งสุดท้ายของคุณจะทำงานได้ยกเว้นว่าคุณไม่มีสิ่ง;ที่จำเป็นในตอนท้ายของคำสั่ง

find . -name "*.py" -type f -exec grep "something" {} \; > output.txt

หากคุณต้องการให้แต่ละรันgrepสร้างเอาต์พุตไปยังไฟล์อื่นให้รันเชลล์เพื่อคำนวณชื่อไฟล์เอาต์พุตและทำการเปลี่ยนทิศทาง

find . -name "*.py" -type f -exec sh -c 'grep "something" <"$0" >"$0.txt"' {} \;

อันสุดท้ายดีมาก: D
bakytn

หากต้องการขยายคำตอบ @gilles เพื่อให้ข้อมูลมากขึ้นโดยเฉพาะหากรายการไฟล์ที่คุณติดต่อมีขนาดใหญ่คุณสามารถรายงานชื่อไฟล์ (เส้นทางสัมพัทธ์) ของแต่ละไฟล์พร้อมกับผลลัพธ์ grep'ed โดยใช้สิ่งนี้ : find . -name "*.py" -type f -exec grep "something" {} \; -print > output.txt และหากคุณต้องการดูหมายเลขบรรทัดของ grep'ed ที่คุณสามารถทำได้ให้ใช้grep -n "something"
JJMpls

9

สำหรับเร็กคอร์ดgrepมี--includeและ--excludeอาร์กิวเมนต์ที่คุณสามารถใช้เพื่อกรองไฟล์ที่ค้นหา:

grep -r --include="*.py" "something" > output.txt

2
อย่างน้อย GNU grepก็ทำเช่นนั้น
phk

2

การใช้tee:

find . -name '*.py' | tee output.txt | xargs grep 'something'

ข้อแม้คือถ้าคุณมีไฟล์ใด ๆ ที่มีอักขระพิเศษ (รวมถึงช่องว่าง) ที่xargsและgrepทำงานได้ไม่ดีกับ ( a file.txtจะถูกตีความว่าเป็นสองไฟล์aและfile.txt) ทางเลือกที่จะที่จะใช้อย่างใดอย่างหนึ่ง-xหรือแต่อย่างใดอย่างหนึ่งของผู้ที่จะก่อให้เกิดมลพิษของคุณ-print0 จะใช้ในการหลบหนีตัวอักษรพิเศษบางอย่างและนี้จะอยู่ใน จะใช้ไบต์โมฆะเป็นตัวคั่นฟิลด์ (ซึ่งยังต้องใช้) และจะมีลักษณะเช่นเส้นที่ต่อเนื่องกันนานหนึ่งของข้อความoutput.txt-x\output.txt-print0xargs -0output.txt

วิธีที่คุณจัดการกับสิ่งนี้ขึ้นอยู่กับคุณ

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