özyinelemeli grep: belirli dizinleri hariç


49

Belirli içeriği olan kaynak dosyaları bulmak için özyinelemeli grep'i çok kullanırım.

grep -Rni "myfunc" .

Büyük kod tabanlarında, bu yavaşlayabilir, bu yüzden / beyaz liste uzantılarını kısıtlamak için -incldue kullanıyorum.

grep -Rni --include=*.java "myfunc" .

Ancak, tüm alt dizinleri dışlamak (budamak) daha verimli olurdu, düşünüyorum:

grep -Rni --exclude=/.svn/ "myfunc" .

Ancak --exclude yalnızca yukarıdaki * .java gibi dosya desenlerini destekler. Dizinleri nasıl hariç tutabilirim?

Yanıtlar:


10

Ack içine bakabilirsiniz .

Kullanmaya yeni başladım ama bunun için çok uygun görünüyor.


ack oldukça iyi görünüyor. hoş olmayan istenmeyen dosyaları dışlatan güzel. --nogroup seçeneği grep -Rni
gabor ile

2
Ack biraz yavaş. Silver Searcher'ı (Ag) veya ripgrep'i (rg) deneyebilirsiniz.
user31389,

62
grep -r --exclude-dir=dev --exclude-dir=sys --exclude-dir=proc PATTERN data

Kaynak: https://stackoverflow.com/questions/2799246/grep-excluding-a-specific-folder-using


17
Bu özyinelemeli hariç olduğunu unutmayın. ./devİLE YAZILACAKTIR ./foo/bar/dev. --exclude-dir=./devSadece ilk davaya başvurmak için kullanın .
Cory Walker

4
Bunu biraz da kısarak da kısaltabilirsiniz: Kürelemeyle bash grep -r --exclude-dir={dev,sys,proc} PATTERN data ilgili tek sorun benim kulağımda çalışmamamdır. Bu durumda onları ayrı tutmam gerekiyor.
b01

3
Ayrıca, {} yalnızca 1'den fazla girdi koyarsanız çalışır, yani --exclude-dir = {home, .svn} çalışır, ancak --exclude-dir = {. Svn} çalışmaz. Neden {} 'nin işe yaramadığını anlamak zamanımı boşa harcıyor çünkü ilk sırada 1 girişle test yapıyorum.
皞 皞

Eğer kullanırsanız {}tek bir giriş ile muhtemelen sistemi bir dizi yapmak için (değil emin nasıl Bash kolları o) bir tekli virgül gerekir. Bunu yapmak yerine .bash_aliases'imde, her zaman dışlamak istediğim bir klasör listesi üzerinde dolaşan bir takma ad oluşturmayı bıraktım, örneğin .git, .svn, .hg, .cache ve sonra bunları bir döngü aracılığıyla eklerim. --exclude-dir $dirve sonra bu diziyi grep takma adına genişletin.
dragon788

6

bunun yerine bulmayı kullanabilirsiniz:

find . -not -path "*/.svn*" -not -type d -exec grep -ni "myfunc" {} \; -print

Tamam, bu biraz geriye doğru, önce grep sonuçlarını ve ardından yolu elde edersiniz . Belki başka birinin daha iyi bir cevabı vardır?


3
tamam, bunu çok beğendim. Tabii ki bulmak çok daha esnek. Çıktı arasındaki tek fark, "grep -Rni" nin her bir eşleşme için dosya adını basması, "find -exec grep" ise dosya ismini bir satır üzerine ve sonra her bir eşleşme için bir satır (satır numarası ve satır içeriği ile) yazacaktır. ). "grep -Hni" kullanmak, her satırda görüntülenecek dosya adını zorlar
gabor

Grep - exclude-dir olmadan ama hala üzerinde çalışılması gereken, bu huysuz sistemler için çalışan tek cevap verdiğiniz için teşekkür ederiz
Dmitri DB 10

2

İşte projelerimden birinde yardımcı olabilecek bir komut dosyasından tam bir örnek, bu dosyayı "all_source" (çalıştırılabilir olarak işaretlenmiş) olarak adlandırıyorum ve projemin kök dizinine koydum ve sonra grep myfunc $(./all_source)komut dosyasının sonundaki sıralama gibi çağır isteğe bağlı.

#!/bin/bash

find . \
    -type d \( \
            -wholename './lib' -o \
            -wholename './vc6' -o \
            -name 'gen' -o \
            -name '.svn' \
            \) -prune -o \
    -type f \( \
            -name '*.h' -o \
            -name '*.cpp' -o \
            -name '*.c' -o \
            -name '*.lua' -o \
            -name '*.*awk' \) -print \
    | sort

Bu komut dosyası, projedeki tüm dosya adlarını döndürür *.h, *.cpp, *.c, *.lua, *.*awk, ancak .svn ve gen klasörleri adındaki tüm klasörlerde arama yapmaz, aynı zamanda ( ./libve ./vc6sadece proje kökünün dışındakileri) klasörlerini atlar . Yani bunu yaptığınızda grep myfunc $(./all_source)sadece bu dosyaları okşar. Bunu projenin kök dizininden de çağırmanız gerekir.


0

Bulmak için -prune seçeneği de vardır:

 find . -path "*/.svn*" -prune -o -not -type d -exec grep -ni "myfunc" {} \; -print

0

Bunu yapmayı deneyebilirsiniz:

grep -R  "myfunc" . | grep -v path_to_exclude/

Örneğin: İçeriği günlük dosyalarında aramak istemiyorsanız, aşağıdakini yapın:

grep -R "myfunc" . | grep -v log/
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.