birden çok dosya türü için grep --include seçeneğini nasıl kullanırım?


100

Bir dizindeki tüm html dosyalarını grep etmek istediğimde aşağıdakileri yapıyorum

grep --include="*.html" pattern -R /some/path

hangisi iyi çalışıyor. Sorun, bir dizindeki tüm html, htm, php dosyalarını nasıl grep edeceğinizdir?

Bundan, grep --exclude / - include sözdizimini belirli dosyalar arasında grep yapmamak için kullanın , görünüşe göre aşağıdakileri yapabilirim

grep --include="*.{html,php,htm}" pattern -R /some/path

Ama ne yazık ki benim için işe yaramaz.
Bilginize, grep sürümüm 2.5.1.

Yanıtlar:


143

Birden çok --includebayrak kullanabilirsiniz . Bu benim için çalışıyor:

grep -r --include=*.html --include=*.php --include=*.htm "pattern" /some/path/

Ancak, Deruijterönerildiği gibi yapabilirsiniz . Bu benim için çalışıyor:

grep -r --include=*.{html,php,htm} "pattern" /some/path/

Kullanabileceğiniz unutmayın findve xargshiç bu tür bir şey için:

find /some/path/ -name "*.htm*" -or -name "*.php" | xargs grep "pattern"

HTH


1
Sorunu görüyorum. Kabuğun genişlemesini önlemek için --include = " . {Html, php}" kullandım ve aynı zamanda kabuğu {html, php} 'yi genişletmek için durdurdu. Görünüşe göre eşittir işareti --include = * kabuğun '*' genişlemesini engelleyebiliyor.
tianyapiaozi

xargs gerçekten bir ikame değildir; Çoğu zaman bu özelliğe ihtiyaç duyduğunuzda, xargs'ın işleyebileceğinden daha fazla dosyayla uğraşıyorsunuz.
James Moore

2
@JamesMoore: GNU Parallel'e bir göz atın . Genellikle bunun yerine kullanılabilir xargs. Bu aynı zamanda hızlı bir okumaya değer. HTH.
Steve

3
@tianyapiaozi: Ayraç genişlemesinin etrafındaki alıntıların sorun olduğu konusunda haklısınız; alıntı olmadan, ancak, *yine de globbing tabidir o gömülü olduğu belirteç parçası olarak , sadece olmuyor sadece dosyaları, çünkü bu durumda maç şey değil kelimenin tam anlamıyla böyle adlandırılmış bir şey --include=foo.htmleşleşir. Güvende olmak için *(ile bireysel olarak yapabilirsiniz) alıntı yapın \*. Ek bir bonus olarak bu, bu durumda globbing'i gerçekleştirmesi gereken kabuğun olmadığını görsel olarak daha net hale getirir .
mklement 0

2
Çözüme gelince find: -exec grep "pattern" {} +yerine kullanmak | xargs grep "pattern"daha sağlam (örneğin, boşluklarla dosya adlarını işler) ve daha etkilidir.
mklement0

32

Kullanımı {html,php,htm}sadece olarak çalışabilir ayracı genişleme standart olmayan bir (POSIX uyumlu değil) özelliğidir, bash, ksh, ve zsh.

  • Başka bir deyişle: onu hedefleyen bir komut dosyasında /bin/shkullanmaya çalışmayın - bu durumda açık birden çok --includeargüman kullanın .

  • grepkendisi vermez değil anlamaya {...}gösterimi.

Bir küme ayracı genişletmesinin tanınması için, komut satırında tırnaksız ( a'nın parçası) bir belirteç olması gerekir .

Bir bağ genişleme genişler birden argümanlar eli o kadar halinde, grepgörerek uçları birden --include=... hepsini ayrı ayrı geçmişti sadece sanki seçenekleri.

Küme ayracı genişletmesinin sonuçları , tuzakları olan globbing'e (dosya adı genişletme) tabidir :

  • Sonuçta ortaya çıkan her bağımsız değişken, .tk gibi tırnaksız genelleme meta karakterleri içeriyorsa eşleşen dosya adlarına genişletilebilir *.
    Bu gibi belirteçlerde --include=*.html(örneğin, eşleşecek bir şey gibi kelimenin tam anlamıyla adlandırılmış bir dosyaya sahip olmanız gerekir --include=foo.html), ancak genel olarak akılda tutmaya değer.

  • nullglobKabuk seçeneği açılırsa ( shopt -s nullglob) ve globbing hiçbir şeyle eşleşmezse , argüman atılır .

Bu nedenle, tamamen sağlam bir çözüm için aşağıdakileri kullanın:

grep -R '--include=*.'{html,php,htm} pattern /some/path
  • '--include=*.'tek tırnaklı olması nedeniyle değişmez olarak değerlendirilir ; bu , bir globbing karakterinin yanlışlıkla yorumlanmasını önler .*

  • {html,php,htm}- zorunluluk - işlem görmeyen bağ genişleme [1] , genişler 3 nedeniyle, bağımsız değişkenler, {...} doğrudan aşağıdaki '...'belirteç , içerir belirteç.

  • Bu nedenle, kabuk tarafından alıntı kaldırıldıktan sonra , aşağıdaki 3 değişmez argüman sonuçta iletilirgrep :

    • --include=*.html
    • --include=*.php
    • --include=*.htm

[1] Daha doğrusu, tırnaksız olması gereken yalnızca küme ayracı genişletmesinin sözdizimiyle ilgili kısımlarıdır; liste öğeleri yine de tek tek alıntılanabilir ve eğer küme ayracı genişletmeden sonra istenmeyen genellemeye neden olabilecek globbing meta karakterleri içeriyorlarsa; bu durumda gerekli olmamakla birlikte, yukarıdakiler şu şekilde yazılabilir:
'--include=*.'{'html','php','htm'}


1
Bu yazı için çok teşekkür ederim. Harika gönderiler yalnızca soruyu yanıtlamakla kalmaz, size yeni bir şey öğretir! Bu, özellikle POSIX uyumlu olması gereken bir şey üzerine yazan bizler için yararlıdır. Mac OS X kullanan herkes buraya bakmalı!
sabalaba

@sabalaba: Bunu duyduğuma sevindim, ama net olmak gerekirse: küme ayracı genişletmesi POSIX uyumlu olmasa da, bashüzerinde bashçalışan herhangi bir platformda çalışır.
mklement0

9

Çift tırnak işaretlerini kaldırmayı deneyin

grep --include=*.{html,php,htm} pattern -R /some/path

1
@tianyapiaozi Dene grep --include=\*.{html,php,htm} pattern -R /some/path. Benim için çalıştı.
Hyunjun Kim

4

bu çalışmıyor mu?

  grep pattern  /some/path/*.{html,php,htm} 

Pek sayılmaz. Dosyalar alt dizinin alt dizininde bulunabilir
tianyapiaozi

2

Bunu dene. -r özyinelemeli arama yapacak. -s dosya bulunamadı hatalarını bastırır. -n size kalıbın bulunduğu dosyanın satır numarasını gösterecektir.

    grep "pattern" <path> -r -s -n --include=*.{c,cpp,C,h}

Bu özellikle benim için en iyi cevap ve bence -r -s -n yerine -rsn koyabilirsiniz (ama bu nitpicking).
slim

Genellikle -rns kullanırım . Örnekte açıklık olması için -r -n -s'den bahsetmek zorunda kaldım :-) Yardımcı olduğu için sevindim.
Pradeep

-IStandart sete eklemenizi tavsiye ederim . Neredeyse hiç aranmayan ikili dosyaları atlayarak verimliliği artırır. Sonra grep -rIns ...akustik güzelce çalan gidiyoruz :)
kanlı

2

Aynı amaç için çalışır, ancak --includeseçeneği yoktur. Grep 2.5.1 üzerinde de çalışıyor.

grep -v -E ".*\.(html|htm|php)"

0

Kullanımı grepile findkomuta

find /some/path -name '*.html' -o -name '*.htm' -o -name '*.php' -type f 
 -exec grep PATTERN {} \+

-regexVe -regextypeseçeneklerini de kullanabilirsiniz .

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.