Dizinleri grep -R'den nasıl hariç tutabilirim?


669

"Node_modules" dizini dışında tüm alt dizinleri geçmek istiyorum.



14
Sadece "man grep" yazın ve orada listelenen --exclude ve --exclude-dir seçeneklerini göreceksiniz - bu sorunun başlığından, grep hakkında zaten bildiğinizi varsayıyorum ...
arcseldon

35
Eğer bir git deposunda kodu grepping ve varsa node_modulesGözlerinde farklı olduğu .gitignore, git grep "STUFF"en kolay yoludur. git grepçalışma ağacında izlenen dosyaları arar, her şeyi yok .gitignore
sayar

2
Düğüm için bir örnek: grep -R --exclude-dir={node_modules,bower_components} "MyString" | cut -c1-"$COLUMNS"- ayrıca her zaman bu kabuğunda 'düğüm' veya başka bir şey için takma olabilir ve dize girişi olarak bir komut argümanı kullanabilirsiniz ..
bshea

Yanıtlar:


394

ÇÖZÜM 1 (birleştir findve grep)

Bu çözümün amacı grepperformansla uğraşmak değil, taşınabilir bir çözüm göstermektir: ayrıca 2.5'ten eski meşgul kutusu veya GNU sürümü ile çalışmalıdır.

findFoo ve bar dizinleri hariç tutmak için kullanın :

find /dir \( -name foo -prune \) -o \( -name bar -prune \) -o -name "*.sh" -print

Ardından , taşınabilir bir çözüm olarak birleştirin findve özyinelemesiz kullanımı grep:

find /dir \( -name node_modules -prune \) -o -name "*.sh" -exec grep --color -Hn "your text to find" {} 2>/dev/null \;

ÇÖZÜM 2 (özyinelemeli kullanımı grep):

Bu çözümü zaten biliyorsunuz, ancak en yeni ve verimli çözüm olduğu için ekliyorum. Bunun daha az taşınabilir ancak insan tarafından okunabilir bir çözüm olduğunu unutmayın.

grep -R --exclude-dir=node_modules 'some pattern' /path/to/search

Birden çok dizini hariç tutmak için --exclude-dirşu şekilde kullanın :

--exclude-dir={node_modules,dir1,dir2,dir3}

ÇÖZÜM 3 (Ag)

Sık sık kod içinde arama yaparsanız, Ag (The Silver Searcher) grep'e çok daha hızlı bir alternatiftir, bu da arama kodu için özelleştirilmiştir. Örneğin, içinde listelenen dosyaları ve dizinleri otomatik olarak yok sayar .gitignore, böylece aynı hantal hariç tutma seçeneklerini grepveya seçeneğine geçirmeye devam etmeniz gerekmez find.


2
bu kombinasyon daha hızlı arama yapar --exclude-dir=dirve renkleri ile sonuçları gösterir - okunması kolay
Maxim Yefremov

27
"bu kombinasyon" benden find ... -execdaha hızlı değil grep --exclude-dir. Bul / exec kombo için \;ile değiştirmediğiniz sürece, grep için büyük avantaj (26k + dosya ile yaklaşık beş kat daha hızlı, HDD'de 38k + 'dan filtrelenmiş) +. O zaman grep "sadece" yaklaşık% 30 daha hızlıdır. Grep sözdizimi de insan tarafından okunabilir :).
Kjell Andreassen

Anlaşıldı, çünkü bu açık. Bazı meşgul kutularında GREP komutu yoktur.
hornetbzz

10
Ayrıca ile birden fazla hariç tutabilirsiniz--exclude-dir={dir1,dir2}
suh

4
node_modulesKanonik örnek olan en az sürpriz değilim .
pdoherty926

983

GNU Grep'in son sürümleri (> = 2.5.2 ) şunları sağlar:

--exclude-dir=dir

kalıpla eşleşen dirdizinleri özyinelemeli dizin aramalarından hariç tutar .

Böylece şunları yapabilirsiniz:

grep -R --exclude-dir=node_modules 'some pattern' /path/to/search

Sözdizimi ve kullanımı hakkında daha fazla bilgi için bkz.

Daha eski GNU Greps ve POSIX Grepfind için diğer yanıtlarda önerildiği gibi kullanın .

Veya sadece ack( Düzenle : veya Gümüş Arayıcı ) kullanın ve onunla işinizi yapın !


4
@Manocho: ackHarika olduğunu düşünüyorsanız , Silver Searcher'ı deneyin ve hız artışını görün!
Johnsyweb

30
Sabırsızlar için sözdizimi: kabuğun dosya yırtılmasını değil , düzenli ifade kalıplarını --exclude-dir=dirkullanır . Desenler, geçerli dizininize göre yollarda çalışır. Öyleyse desen kullanın , değil . grep--exclude-dir=dir--exclude-dir="/root/dir/*"
tanius

15
Birden fazla dizini arama dışında bırakmak istiyorsanız, kullanmaktan daha iyi bir seçenek var $ grep -r --exclude-dir=dir1 --exclude-dir=dir2 "string" /path/to/search/dirmı?
Darshan Chaudhary

4
Muhtemelen bu konuda herhangi bir aklı başında insandan çok fazla zaman geçirdim, ama hayatım boyunca bir alt dizini arama grep -r --exclude-dir=public keyword .çalışmalarından nasıl hariç tutacağımı anlayamıyorum - ama grep -r --exclude-dir='public/dist' keyword .değil. Normal ifade joker karakterlerini, kaçan karakterleri vb.
dkobozev

73
Bunun gibi birden fazla dizini hariç grep -r "Request" . --exclude-dir={node_modules,git,build}
maverick97

78

Birden çok dizini hariç tutmak istiyorsanız :

özyinelemeli "r", yalnızca eşleşme içeren dosyaların adlarını yazdırmak için "l" ve büyük / küçük harf ayrımlarını yoksaymak için "i":

grep -rli --exclude-dir={dir1,dir2,dir3} keyword /path/to/search

Örnek: 'Merhaba' kelimesini içeren dosyaları bulmak istiyorum. Proc dizini, önyükleme dizini, sys dizini ve kök dizini hariç tüm linux dizinlerimde arama yapmak istiyorum :

grep -rli --exclude-dir={proc,boot,root,sys} hello /

Not: Yukarıdaki örneğin kök olması gerekir

Not 2 (@skplunkerin'e göre): içindeki virgüllerden sonra boşluk eklemeyin {dir1,dir2,dir3}


5
NOT: virgül sonra boşluk eklemeyin{dir1,dir2,dir3}
skplunkerin

Teşekkürler, SVN çalışma alanında grep'ing yaparken kullanışlı:grep -Irsn --exclude-dir=.svn 'foo' .
RAM237

1
--exclude-dirSeçeneği birden çok kez sağlayabilirsiniz .
Walf

44

Bu sözdizimi

--exclude-dir={dir1,dir2}

kabuk tarafından genişletilmez (örn. Bash), bununla değil grep:

--exclude-dir=dir1 --exclude-dir=dir2

Alıntı yapmak kabuğun onu genişletmesini önleyecektir, bu yüzden çalışmaz:

--exclude-dir='{dir1,dir2}'    <-- this won't work

Birlikte kullanılan --exclude-dirmodeller, --excludeseçenek için kılavuz sayfasında açıklananla aynı desenlerdir :

--exclude=GLOB
    Skip files whose base name matches GLOB (using wildcard matching).
    A file-name glob can use *, ?, and [...]  as wildcards, and \ to
    quote a wildcard or backslash character literally.

Kabuk genellikle böyle bir deseni genişletmeye çalışır , bu nedenle bundan kaçınmak için alıntı yapmalısınız:

--exclude-dir='dir?'

Kıvırcık parantezleri kullanabilir ve alıntılanan desenleri şu şekilde birlikte hariç tutabilirsiniz:

--exclude-dir={'dir?','dir??'}

Bir desen, birden çok yol parçasına yayılabilir:

--exclude-dir='some*/?lse'

Bu, aşağıdaki gibi bir dizini hariç tutar topdir/something/else.


13

Bunu sık sık kullanın:

grep-r(özyinelemeli), i(yoksayma durumu) ve -o(satırların yalnızca eşleşen bölümlerini yazdırır ) ile birlikte kullanılabilir . Dışlamak için fileskullanılmasını --excludeve dizinleri kullanımını dışlamak için --exclude-dir.

Bir araya getirmek şöyle bir şeyle sonuçlanır:

grep -rio --exclude={filenames comma separated} \
--exclude-dir={directory names comma separated} <search term> <location>

Bunu tanımlamak, kulağa olduğundan daha karmaşık gelmesini sağlar. Basit bir örnekle açıklamak daha kolaydır.

Misal:

debuggerBir hata ayıklama oturumu sırasında dize değerini açıkça ayarladığım ve şimdi gözden geçirmek / kaldırmak istediğiniz tüm yerler için geçerli proje aradığımı varsayalım .

Ben denilen bir komut dosyası yazmak findDebugger.shve greptüm oluşumları bulmak için kullanın . Ancak:

Dosya hariç .eslintrctutmaları için - göz ardı edildiğinden emin olmak istiyorum (bu aslında bir dışlama kuralına sahiptir, bu debuggernedenle hariç tutulmalıdır). Benzer şekilde, kendi komut dosyama herhangi bir sonuçta başvurulmasını istemiyorum.

Hariç tutulan dizinler için - Çok node_modulessayıda kitaplık içerdiğinden dışlamak istiyorum debuggerve bu sonuçlarla ilgilenmiyorum. Ayrıca, sadece arama dizinlerini de umursamadığım ve arama performansını korumak istediğim için dizinleri atlamak .ideave gizlemek .gitistiyorum.

İşte sonuç - Ben findDebugger.shile adlandırılan bir komut dosyası oluşturmak :

#!/usr/bin/env bash
grep -rio --exclude={.eslintrc,findDebugger.sh} \
--exclude-dir={node_modules,.idea,.git} debugger .

"R" seçeneğinin büyük harf "-R" ile basılması gerektiğine inanıyorum.
hornetbzz

1
İlginç. "r" her zaman benim için nix ve mac üzerinde çalıştı.
arcseldon

Cevabımı yazdığımda kullandım -R(neden şimdi hatırlamıyorum). Genellikle kullanıyorum -r. Büyük harfli versiyonun sembolik bağlantıları takip ettiği ortaya çıkıyor . TIL.
Johnsyweb

@Johnsyweb - teşekkürler. Cevabınızı kaldırdı - ne zaman hatırlamıyorum, 2016 yılında bunu eklediğimde :)
arcseldon

10

Gibi bir şey deneyebilirsin grep -R search . | grep -v '^node_modules/.*'


34
Bazı durumlarda böyle iyi bir çözüm değil. Örneğin: 'node_modules' dizini çok sayıda yanlış pozitif eşleşmeye sahip büyük bir dizinse (bu nedenle dizini filtreleme ihtiyacı), o zaman ilk grep bir alt dizinde arama yapmaktan çok zaman kaybediyor ve daha sonra ikinci grep filtrelemesi maçlar. İlk grep'in kendisinde node_modules'ü hariç tutmak daha hızlıdır.
GuruM

2
Yavaşlık umurumda değil, komuta bakabilir ve ne yaptığını bilirim
Funkodebat

1
Guru'nun yorumu için Ditto. Benim durumumda /varvurduğunda bir grep asılı /var/run. Bu nedenle öncelikle dizinden kaçınmak istiyorum.
jww

3
--exclude-dir
Omar Tarık

10

Eğer bir git deposunda kodu grepping ve varsa node_modulesGözlerinde farklı olduğunu .gitignore, kullanabilirsiniz git grep. git grepçalışma ağacındaki izlenen dosyaları arar ve her şeyi yok sayar..gitignore

git grep "STUFF"

Bu çok yararlı bir ipucu.
NKM

4

Özellikle "node_modules" içinde arama yapmaktan kaçınmak istediğimiz Node.js ile ilgilenenler için çok kullanışlıdır :

find ./ -not -path "*/node_modules/*" -name "*.js" | xargs grep keyword

2

Basit bir çalışma komutu:

root/dspace# grep -r --exclude-dir={log,assetstore} "creativecommons.org"

Yukarıda "dspace" dizinindeki "creativecommons.org" metnini okudum ve dirs {log, assettore} 'ı hariç tutuyorum.

Bitti.


Parantez içinde çeşitli dizinler de dahil olmak üzere temiz
Mijo

2

Burada birçok doğru cevap verilmiştir, ancak bunu daha önce başarısız olan bazı acele denemelerine neden olan bir noktayı vurgulamak için ekliyorum: bir dizine giden bir yol değil exclude-dir, bir desen alır .

Aramanızın:

grep -r myobject

Ve çıktınızın sonuçları ile darmadağın olduğunu fark edin src/other/objects-folder. Bu komut olacak değil size amaçlanan sonuç verecektir:

grep -r myobject --exclude-dir=src/other/objects-folder

Ve neden exclude-dirçalışmadığını merak edebilirsiniz ! Sonuçları gerçekten hariç tutmak için şunu yapın objects-folder:

grep -r myobject --exclude-dir=objects-folder

Başka bir deyişle, yolu değil klasör adını kullanın . Bunu bildiğinizde belli.

Man sayfasından:

--exclude-dir = GLOB GLOB
deseniyle eşleşen bir ad sonekine sahip tüm komut satırı dizinlerini atlayın. Özyinelemeli arama yaparken, taban adı GLOB ile eşleşen tüm alt dizinleri atlayın. GLOB'daki gereksiz sondaki eğik çizgileri yoksayın.


2

Bu benim için çalışıyor:

grep <stuff> -R --exclude-dir=<your_dir>

5
Bu cevap, daha önce gönderilmiş olan cevaplardan nasıl farklı?
aexl


-1

Daha basit bir yol, sonuçlarınızı "grep -v" kullanarak filtrelemektir.

grep -i needle -R * | grep -v node_modules


12
Bu, DipSwitch'in 3 yıl önce verdiği aynı cevaptır. Aynı problemleri de var.
jww
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.