ฉันจะ "grep" กรองชื่อซ้ำของไฟล์ที่ต้องการด้วย wildcard ได้อย่างไร


40

เมื่อฉันต้องการทำการค้นหา grep ซ้ำในไดเรกทอรีปัจจุบันฉันมักจะทำ:

grep -ir "string" .

แต่คำสั่งนั้นจะค้นหาไฟล์ทุกชนิดรวมถึงไฟล์ไบนารี่ (รูปภาพ, เสียง, วิดีโอ, ฯลฯ ... ) ซึ่งส่งผลให้กระบวนการค้นหาช้ามาก

ถ้าฉันทำสิ่งนี้มันจะไม่ทำงาน:

grep -ir "string" *.php

ใช้งานไม่ได้เนื่องจากไม่มีไฟล์ PHP อยู่ในไดเรกทอรีปัจจุบัน แต่ภายในไดเรกทอรีย่อยบางส่วนในไดเรกทอรีปัจจุบันและชื่อของไดเรกทอรีย่อยไม่ได้ลงท้ายด้วย ".php" ดังนั้น grep จึงไม่ดูข้างใน

ดังนั้นฉันจะค้นหาแบบเรียกซ้ำจากไดเรกทอรีปัจจุบัน แต่ยังระบุสัญลักษณ์แทนชื่อไฟล์ได้อย่างไร (เช่น: ค้นหาเฉพาะไฟล์ที่ลงท้ายด้วยนามสกุลเฉพาะ)

คำตอบ:


58

การใช้งานgrepของ--includeตัวเลือก:

grep -ir "string" --include="*.php" .

1
ตกลงดูเหมือนว่า grep รุ่นเก่าของฉันเพราะมันไม่มีตัวเลือกนั้น (ไม่แปลกใจเลยว่าทำไมฉันถึงไม่สามารถรู้วิธีการทำสิ่งนี้!) ฉันได้รับข้อความ: "grep: ตัวเลือกที่ไม่รู้จัก` --include = *. php '" แต่ฉันเพิ่งอัพเกรดเป็นรุ่นใหม่และตอนนี้มันใช้งานได้ ขอขอบคุณ!
OMA

ฉันต้องเปลี่ยนช่วงเวลาในตอนท้ายและใช้:grep -ir "string" --include="*.php" *
สจวร์ต

ฉันคิดว่าช่วงเวลานั้นเป็นแค่จุดสิ้นสุดของเส้น! ฉันไม่ได้ใช้หรือต้องการ
boardtc

14

หากคุณมีรุ่นgrepที่ไม่มี--includeตัวเลือกคุณสามารถใช้สิ่งต่อไปนี้ ทั้งคู่ถูกทดสอบในโครงสร้างไดเร็กทอรีเช่นนี้:

$ tree
.
├── a
├── b
   └── foo2.php
├── c
   └── d
       └── e
           └── f
               └── g
                   └── h
                       └── foo.php
├── foo1.php
└── foo.php

ที่ทุกไฟล์ที่มีสตริง.phpstring

  1. ใช้ find

    $ find . -name '*php' -exec grep -H string {} +
    ./b/foo2.php:string
    ./foo1.php:string
    ./c/d/e/f/g/h/foo.php:string
    

    คำอธิบาย

    นี่จะค้นหา.phpไฟล์ทั้งหมดแล้วเรียกใช้grep -H stringในแต่ละไฟล์ กับfind's -execตัวเลือก{}จะถูกแทนที่ด้วยแต่ละไฟล์ที่พบ การ-Hบอกgrepให้พิมพ์ชื่อไฟล์เช่นเดียวกับบรรทัดที่ตรงกัน

  2. สมมติว่าคุณมีเวอร์ชันใหม่เพียงพอbashให้ใช้globstar:

    $ shopt -s globstar
    $ grep -H string  **/*php
    b/foo2.php:string
    c/d/e/f/g/h/foo.php:string
    foo1.php:string
    

    คำอธิบาย

    ตามที่อธิบายไว้ในคู่มือทุบตี :

    GLOBSTAR

    หากตั้งค่ารูปแบบ '**' ที่ใช้ในบริบทการขยายชื่อไฟล์จะจับคู่ไฟล์ทั้งหมดและไม่มีค่าไดเรกทอรีและไดเรกทอรีย่อยหรือมากกว่า หากรูปแบบตามด้วย '/' จะมีเพียงไดเรกทอรีและไดเรกทอรีย่อยเท่านั้นที่ตรงกัน

    ดังนั้นโดยการทำงานshopt -s globstarที่คุณกำลังเปิดใช้งานคุณลักษณะและทุบตีของglobstarตัวเลือกซึ่งจะทำให้การ**/*phpขยายไปยังทุก.phpไฟล์ในไดเรกทอรีปัจจุบัน ( **ตรงกับ 0 หรือมากกว่าไดเรกทอรีเพื่อให้**/*phpตรง./foo.phpเช่นกัน) ซึ่งได้รับการ grepped stringแล้ว


-2

ใช้ */*.php

สิ่งนี้ทำให้ grep ค้นหาไดเรกทอรีย่อยหนึ่งระดับ


มีบางอย่างผิดพลาดเมื่อเครื่องหมายดอกจันและจุดหายไป
Dennis Nolan

คุณสามารถใช้ backticks เพื่อจัดรูปแบบรหัสและหลีกเลี่ยงความคลุมเครือเกี่ยวกับการใช้เครื่องหมายดอกจันเพื่อเน้นการจัดรูปแบบเครื่องหมาย หมายเหตุ PS คำถามถามเกี่ยวกับ "การค้นหาซ้ำ" ในวรรคสุดท้าย (ไม่ใช่ downvote ของฉันแม้ว่า)
RedGrittyBrick

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