`Grep` kullanarak bir PHP dosyasındaki bir dizeyi nasıl arayabilirim?


11

Yüzlerce PHP dosyası içeren bir sitede sınıf bildirimi arıyorum. Bunu grep kullanarak geçerli klasörde ve alt klasörlerde nasıl yapabilirim ?

cdKlasöre girdim ve daha sonra

grep -r 'class MyClass' *.php

Bu, süper kullanıcıya geçtiğinde, size grep -rvermeyen, istediğiniz şey hakkında bir şeyler söylemek isteyebilirsiniz .

Kafam karıştı - sadece kendine cevap vermedin mi? o hattın sonuçları nelerdi? daha da optimize etmeye mi çalışıyorsunuz? lütfen bu soruyu başka biri olarak okumayı düşünün, çünkü kafa karıştırıcı ve belirsizdir.
meder omuraliev

@other yorumlar: His grep -r deyimi o bütün klasörleri php ile sona sürece ... muhtemelen böyle değildir ki, ne istediğini vermiyor
David Oneill

Hiç bir şey alamadım. Ben işe yaramadı varsayalım çünkü bu sınıf ile dosyayı içeren klasörde im bulduğunda biliyorum

Dosyayı şans eseri buldum. Bu satırla PHP dosyasının bulunduğu klasörde dosyayı ararken, dosyayı bulur (-r'ye gerek yoktur). Ben kök CD ve özyineleme -r ile arama yaparsanız hiçbir şey döndürmez.

Yanıtlar:


24

Deneyebilirsin

grep -r --include=*.php "search string" /path/to/dir

1
Harika çalışıyor. Unutmaya devam ediyorum, ama neyse ki bana her zaman bir cevap daha var. :)
GolezTrol

@GolezTrol Bunu bilmek sevindim :-)
rahul286

9

Bir grep ile yapmak yerine ctags gibi bir şey kullanmanızı tavsiye ederim . Ancak, isterseniz, böyle bir şey yapabilirsiniz

 find <top level dir> -name \*.php | xargs grep "class MyClass"

Bu, elbette, aralarında yalnızca doğru bir boşluk olduğunu varsayar classve myClassbunlar doğru olmayabilir. Gerçi herhangi bir sayıda beyaz boşluk aramak için normal ifadeyi değiştirmek kolaydır.


4

Kullanıyorsanız -r, büyük olasılıkla yalnızca geçerli dizini özyinelemeli olarak aramak istersiniz :

grep -r 'class MyClass' .

Yukarıdakilerin sonundaki noktaya dikkat edin.

Söylediğiniz grepşey, her *.phpdosyayı veya dizini özyinelemeli olarak aramasını istediğinizdi , ancak büyük olasılıkla .php uzantısıyla biten dizinleriniz yoktu. Yukarıda arama yapmak mümkün olan en basit yoludur, ancak her yerde .svn dizinleri olduğunda özellikle sorunlu olan diğer tür dosyaları içerir. Çok fazla başka dosya türünüz yoksa, yukarıdakiler genellikle yeterlidir ve iyi çalışır.

Çoğu grep enkarnasyonunda, aranabilen dosya uzantılarını belirtmenin bir yolu yoktur, bu nedenle genellikle find'ı onunla birlikte kullanırsınız:

find <startDir> -iname '*.php' -exec grep 'class[ \t]*MyClass' {} \;

-inamegrep'in bazı sürümlerinde büyük / küçük harfe duyarlı olmayan bir dosya adı araması yapmak istediğinizi söyler, ancak find'ın GNU olmayan varyantlarının çoğu bunu desteklemez, -namebunun yerine kullanabilirsiniz .

Yukarıdaki -execseçenek, her dosya için grep'i çağırmanın yan etkisine sahiptir, bu da oldukça pahalıdır.

Yine de grep'in diğer sürümleri +, çalıştırılabilir dosyanın çağrılma sayısını azaltmak için argümanları bir araya getirmeyi söyleyen bir desteği destekler :

find <startDir> -iname '*.php' -exec grep 'class[ \t]*MyClass' {} + \;

Çağrıları azaltmak için sıkça önerilen bir yol, grep'i mümkün olduğunca az kez, ancak gerektiği kadar ateşleyecek xargs kullanmaktır:

find <startDir> -iname \*.php | xargs grep "class[ \t]*MyClass"

xargsgrep'i komut satırında desteklenen maksimum argüman sayısına kadar aktaracak kadar akıllıdır, ancak yukarıdaki varyasyon boşluklar gibi belirli karakterleri çok iyi işlemez. Örneğin, 'file.php' dosya adı grep'inin argüman olarak 'the' ve argüman olarak 'file.php' alacağı için her ikisi de bulunamazdı. Bunun yerine şunları kullanıyoruz:

find <startDir> -iname \*.php -print0 | xargs -0 grep "class[ \t]*MyClass"

print0ve -0birlikte çalışma ve kullanım bağımsız değişkenleri bağımsız değişken tam ve açık bir şekilde tanımlanır, böylece bir boş karakter takip eder.

daha sonra birden fazla alanınız classveya bir sekmeniz varsa, normal ifadeyi değiştirerek daha fazla karaktere izin vermek isteyebilirsiniz:class[ \t]*MyClass

Bu mesaj StackOverflow'daki diğer örnekler vardır ve .svn dizinleri gibi belirli dizinleri dışlamak için nasıl kullanılacağını gösterir.


Bu, tüm dosyaları arar. Ayrıca .php dosyası olmayan dosyalar.
GolezTrol

Yayını başka birçok örnek içerecek şekilde güncelledim.
Kaleb Pederson


1
grep -r 'class MyClass' *.php

.php ile biten tüm klasörlerde arama yapar

grep -r 'class MyClass' . | grep .php

tüm alt klasörlerde bulunan tüm dosyalarda MyClass sınıfını arayacak, sonra yalnızca .php olanları döndürecektir.


1

find . -type f -name *.php -print -exec grep \"class MyClass\" {} \; size bulunduğu satırın içeriğini ve dosyanın yolunu verecektir.


1

Eşleşen dosyaların rastgele adları olabilirse, -print0

bulmak. tipi f-adı '* .php' -print0 | xargs -0 grep 'sınıf MyClass'


1
grep -rl 'class MyClass' . --include \*.php

sadece dosya adını gösterdim

r tekrarlanır

. geçerli klasörde arama yapar

- dosya adı uzantısını sınırlar dahil et


1

Muhtemelen büyük / küçük harf duyarsızlığı ve boşluk toleransı istersiniz ve grep, geçerli dizinde istenen dosya deseninin herhangi bir örneğini bulamazsa sonlanır. Nereden başlayacağını bilmeli ve olduğu gibi eşleşen hiçbir dosya başlangıç ​​yolu oluşturmaz.

İstenen uzantının en az bir dosyası varsa, egrep -ir komutunu kullanabilirsiniz. findve xargsgrep'in başarısız olduğu tek düz (ancak çok büyük) dizinlerle ve ekstra niteleyicilerle (örneğin yalnızca .inc, .php ve php3 dosyalarını aramak istiyorsanız) güçlerini gösterin. Ama benim deneyimimde biraz rahatlık ve hız kaybediyor. İnsan yazılı sınıf beyannameleri için büyük bir sorun boşluk olacaktır. Bu yüzden grep yerine egrep kullanın. Ayrıca ekstra hız için LC_ALL = C. Kolaylık sağlamak için sık sık kullanıyorum:

LC_ALL=C egrep -irn "class[ ]*myclass([ ]|\n)" * | egrep "\.(inc|php[35]?)"

-i -- case insensitive
-r -- recursive for all file pattern (here *)
-n -- include the line number
LC_ALL=C -- search in ASCII, not in utf8, this is much faster.

[ ]* -- match any number of spaces before the class name
([ ]|\n) -- match a space or newline after the classname

Bu, yine de yorumlarla eşleşebilir // class myclass exists in file, ancak bunları nispeten küçük buluyorum ve bunlar ile filtrelenebilir... | fgrep -v '//'

Ayrıca, egrep dosya modeline aşağıdaki gibi daha karmaşık dosya maskeleri (örneğin, .inc ve .php dosyalarının çoğunu yakalamak için) dahil edebilirsiniz:

egrep "pattern" *.[ip]*

Bu (ilk seçeneklerle) oldukça hızlı ve çoğunlukla php dosyalarıyla sınırlı olacaktır.

HTH


0

Biliyorum diyor grep, ama benim kişisel favorim kullanmaktır ack-grep:

ack-grep "class MyClass"

Bu özyinelemeli olarak çalışır, bulduğu dosya adını, bulundukları yerdeki satır numaralarını ve vurguları listeler. Özellikle php dosyalarını hedeflemek için çalıştırabilirsiniz:

ack-grep --type-set php:ext:php "path"

Paket çok sayıda seçeneğe sahiptir; Süslü şeyler yapmak için kesinlikle tavsiye ederim (ve ilişkili adam sayfasına göz atarak).

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.