วิธีเรียกใช้ find -exec


477

ฉันต้องการค้นหาไฟล์ในไดเรกทอรีปัจจุบันที่มีข้อความ "chrome"

$ find . -exec grep chrome
find: missing argument to `-exec'

ผมทำอะไรผิดหรือเปล่า?


เกี่ยวข้อง: unix.stackexchange.com/q/321697/135943
Wildcard

ฉันได้รับfind: Only one instance of {} is supported with -exec ... +
คอส

2
ที่เกี่ยวข้อง: วิธีใช้-execกับfind
Kusalananda

คำตอบ:


710

คุณพลาด a ;(หลบหนีมาที่นี่\;เพื่อป้องกันเชลล์จากการตีความ) หรือ a +และ a {}:

find . -exec grep chrome {} \;

หรือ

find . -exec grep chrome {} +

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


30
หากคุณใช้ \; ตอนจบการสร้าง grep ถูกส่งผ่านทีละไฟล์ดังนั้นจึงไม่แสดงชื่อไฟล์ตามค่าเริ่มต้นเฉพาะบรรทัดที่ตรงกัน หากต้องการรับรายการไฟล์ให้เพิ่มการใช้grep -lsภายในการค้นหาโครงสร้าง
Caleb

9
find . -exec grep foo {} +จะแสดงผลลัพธ์เช่นนี้./dir/file.py:from foo import bar
sg

10
find . -exec grep foo {} \;จะแสดงผลลัพธ์เช่นนี้from foo import bar
sg

9
find . -exec grep -l foo {} +จะแสดงผลลัพธ์เช่นนี้./dir/file.py
sg

8
find . -exec grep -l foo {} \;จะแสดงผลลัพธ์เช่นนี้./dir/file.py
sg

46

คุณไม่จำเป็นต้องใช้findสิ่งนี้เลย grep สามารถจัดการการเปิดไฟล์ได้จากรายการ glob ของทุกสิ่งในไดเรกทอรีปัจจุบัน:

grep chrome *

... หรือแม้แต่เรียกซ้ำสำหรับโฟลเดอร์และทุกสิ่งภายใต้:

grep chrome . -R

22
grep จะทำให้หายใจไม่ออกหากการขยายตัวเกิน ARG_MAX -R จะเข้าชมทุกอย่างในขณะที่ใช้ find หนึ่งสามารถเพิ่ม primitives ได้ง่ายขึ้นเพื่อแยกไฟล์บางไฟล์ (-name, etc) หรือไม่แม้แต่ไปที่ subtrees (-prune)
Mel

6
คะแนนที่ดี @Mel ประเด็นของฉันคือว่าในทุกโอกาสฝ่ายที่ร้องขอจะทำสิ่งที่ซับซ้อนกว่าที่พวกเขาต้องการโดยการแนะนำfindเมื่อgrepสามารถทำงานได้ แต่ในบางกรณีมันจะมีประสิทธิภาพมากกว่าที่จะใช้ find เพื่อปรับรายชื่อไฟล์ก่อนออกไปข้างนอก เพื่อ grep
Caleb

4
@Mel grepไม่ทำให้หายใจไม่ออกในกรณีเช่นexecนี้
Chris Down

ใช้งานได้เฉพาะในกรณีที่ไฟล์ทั้งหมดอยู่ในไดเรกทอรีเดียวกันไม่ใช่เมื่อมีการแพร่กระจายไปยังไดเรกทอรีย่อย
Yaba

1
@Yaba คำตอบของฉันระบุวิธีจัดการกรณีของไฟล์ที่กระจายอยู่ในไดเรกทอรีย่อย
คาเลบ

18
find . | xargs grep 'chrome'

คุณสามารถทำได้:

find . | xargs grep 'chrome' -ls

ครั้งแรกจะแสดงบรรทัดในไฟล์ที่สองเพียงแสดงรายการไฟล์

ตัวเลือกของ Caleb คือ neater กดแป้นน้อยลง


11
ปัญหาของxargsมันคือมันคาดว่าอินพุตจะถูกยกมาในรูปแบบที่แปลกประหลาดที่findไม่ได้ผลิต ดังนั้นไม่ทำงานถ้าคุณมีชื่อไฟล์ที่มีช่องว่างหรือfind … | xargs … \'"
Gilles

3
@Gilles คุณสามารถแก้ไขปัญหานั้นได้โดยใช้สิ่งที่ชอบfind . | xargs -n1 -iX grep "X" 'chrome'เพื่อให้ข้อโต้แย้งได้รับการป้อนครั้งละหนึ่งรายการและเสนอราคา เห็นได้ชัดว่านี่เป็นวิธีที่ไม่มีประสิทธิภาพในการจัดการกับตัวอย่างนี้ แต่สำหรับบางสถานการณ์มันก็ดี
Caleb

เพื่อความสมบูรณ์เราควรพูดถึงตัวเลือก -i สำหรับการไม่คำนึงถึงขนาดตัวพิมพ์ด้วย 'grep' นอกจากนี้ยังมี -iname ในการค้นหากรณีตาย
Mathew

9
@Caleb: วิธีเดียวที่เชื่อถือได้ 100% ในการxargsจัดการกับชื่อไฟล์ Linux คือการfind ... -print0 | xargs -0ใช้ NUL เป็นตัวคั่น ทางเลือก - การxargs -d '\n'ใช้บรรทัดใหม่เป็นตัวคั่นความน่าเชื่อถือ 99%
grawity

ฉันใช้สิ่งนี้บ่อย ๆ แต่มันจะล้มเหลวสำหรับรายชื่อไฟล์ที่ยาวมากซึ่งเป็นจุดที่พบว่า -exec กลายเป็นผู้ชนะ
Spacemoose

5

การค้นหาเป็นวิธีหนึ่งและคุณสามารถลองได้the_silver_searcherสิ่งที่คุณต้องทำคือ

ag chrome

มันจะค้นหาโครเมี่ยมในไฟล์ทั้งหมด (รวมถึงไดเรกทอรีย่อย) และมันเร็วกว่าการค้นหา


นอกจากนี้ยังมี pt (ผู้ค้นหาแพลตินัมให้บริการที่github.com/monochromegane/the_platinum_searcher ) ซึ่ง IMHO ทำงานได้เร็วขึ้น - อาจไม่สำคัญว่ามีไฟล์เพียงไม่กี่ไฟล์
Hopping Bunny


1

นี่คือตัวอย่างของวิธีที่ฉันใช้ find / exec ...

find  . -name "*.py" -print -exec fgrep hello {} \;

การค้นหานี้จะวนซ้ำสำหรับไฟล์. py ทั้งหมดและสำหรับแต่ละไฟล์จะพิมพ์ชื่อไฟล์และ fgrep สำหรับ 'hello' ในไฟล์นั้น (สำหรับแต่ละไฟล์) ผลลัพธ์ดูเหมือนว่า (วิ่งแค่วันนี้):

./r1.py
./cgi-bin/tst1.py
print "hello"
./app/__init__.py
./app/views.py
./app/flask1.py
./run.py
./tst2.py
print "hello again"

1
ไม่ยุ่งกับเวิร์กโฟลว์ของคุณ แต่คุณอาจต้องการ: find . -name "*.py" -exec fgrep -l hello {} \; - มันจะพิมพ์ชื่อไฟล์ของไฟล์ที่ตรงกับสิ่งอื่น
Jeff Schaller
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.