Belirli bir dize kalıbı içermeyen dosyaları nasıl bulurum?


Yanıtlar:


818

Grep'inizde -L(veya --files-without-match) seçeneği varsa:

$ grep -L "foo" *

1
Başka bir yerde belirtildiği gibi ack varsayılan olarak .svn (subversion) dosyalarından kaçınmaya yardımcı olur.
GuruM

11
@GuruM Bu, GNU grep'te şu değişken dışa aktarılarak yapılabilir GREP_OPTIONS='--exclude-dir=.svn --exclude-dir=.git': ^)
bufh

6
Veya ag kullanarak eşdeğeri :ag -L 'foo'
bishop

5
Sihir gibi çalışır! İpucu: -rL-L
Alt

1
@Larry - Globbing problemlerinden kaçınmanın daha temiz bir yolu, "boş" uzun seçeneği şu şekilde kullanmaktır: grep -L 'foo' -- *Standart, uzun seçenekleri alan komutların, --bu noktadan sonra başka seçenek olmadığını belirtmektir.
Paddy Landau

45

Bir göz atın ack. .svnOtomatik olarak sizin için dışlama yapar, Perl düzenli ifadeler verir ve tek bir Perl programının basit bir indirmesidir.

Aradığınız şeyin eşdeğeri aşağıdaki gibi olmalıdır ack:

ack -L foo

23

Bunu sadece grep ile (bulmadan) yapabilirsiniz.

grep -riL "foo" .

Bu, üzerinde kullanılan parametrelerin açıklamasıdır. grep

     -L, --files-without-match
             each file processed.
     -R, -r, --recursive
             Recursively search subdirectories listed.

     -i, --ignore-case
             Perform case insensitive matching.

Eğer kullanırsanız ltam tersini alacak (küçük harfli) (maçlarla dosyalar)

     -l, --files-with-matches
             Only the names of files containing selected lines are written

17

Aşağıdaki komut bana kalıbı içermeyen tüm dosyaları verir foo:

find .  -not  -ipath '.*svn*' -exec  grep  -H -E -o -c  "foo"  {} \; | grep 0

4
Sonunda grep 0'ı grep 0 $ olarak değiştirmek istersiniz (aksi takdirde dosya adlarında 0 karakterine sahip dosyalarda hatalı eşleşmeler alırsınız).
clouseau

9
@clouseau çoğunlukla haklı ... Ancak, grep '0$'dosyaları 10 satırın katlarıyla eşleştirebilir! grep ':0$'Sonunda, satırın sonunda açık bir ': 0' olup olmadığını kontrol etmeniz gerekir . O zaman sadece sıfır satır eşleşen dosyaları alırsınız.
TrinitronX

Üzerinde olduğum UNIX, bu seçeneklerle find veya grep sürümlerine sahip değildi, bu yüzden diğer yorumlarda önerilen "ack" komutuyla gitmek zorunda kaldım.
KC Baltz

14

Aşağıdaki komut, bulucunun svnbir saniye kullanarak klasörleri filtrelemesini gerektirmez grep.

grep -rL "foo" ./* | grep -v "\.svn"

9

Aslında ihtiyacınız olacak:

find .  -not  -ipath '.*svn*' -exec  grep  -H -E -o -c  "foo"  {} \; | grep :0\$

6

İle iyi şanslar yaşadım

grep -H -E -o -c "foo" */*/*.ext | grep ext:0

İle yaptığım girişimler grep -vbana sadece "foo" olmadan tüm satırları verdi.


4

Sorun

.phtmlSatır içi PHP kodu kullanarak HTML yazmak için dosyaları kullanan büyük bir proje refactor gerekir . Bunun yerine Bıyık şablonlarını kullanmak istiyorum . Bu hala yeniden yazılması gerekir gibi .phtmldize içermeyen herhangi bir giles bulmak istiyorum new Mustache.

Çözüm

find . -iname '*.phtml' -exec grep -H -E -o -c 'new Mustache' {} \; | grep :0$ | sed 's/..$//'

açıklama

Borulardan önce:

bulmak

find . Bu dizinden başlayarak dosyaları yinelemeli olarak bulun

-iname '*.phtml'Dosya adı içermelidir .phtml( ibüyük / küçük harfe duyarlı değildir)

-exec 'grep -H -E -o -c 'new Mustache' {}'grepEşleşen yolların her birinde komutu çalıştırın

grep

-H Dosya adı başlıklarını her zaman çıktı satırlarıyla yazdırın.

-E Deseni genişletilmiş düzenli bir ifade olarak yorumlar (yani grep'i egrep gibi davranmaya zorlar).

-o Çizgilerin yalnızca eşleşen kısmını yazdırır.

-c Standart çıktıya yalnızca seçili satır sayısı yazılır.


Bu .phtml, dizenin new Mustacheher birinde kaç kez oluştuğunu sayarak, biten tüm dosya yollarının bir listesini verecektir .

$> find . -iname '*.phtml$' -exec 'grep -H -E -o -c 'new Mustache' {}'\;

./app/MyApp/Customer/View/Account/quickcodemanagestore.phtml:0
./app/MyApp/Customer/View/Account/studio.phtml:0
./app/MyApp/Customer/View/Account/orders.phtml:1
./app/MyApp/Customer/View/Account/banking.phtml:1
./app/MyApp/Customer/View/Account/applycomplete.phtml:1
./app/MyApp/Customer/View/Account/catalogue.phtml:1
./app/MyApp/Customer/View/Account/classadd.phtml:0
./app/MyApp/Customer/View/Account/orders-trade.phtml:0

İlk boru, grep :0$bu listeyi yalnızca ile biten satırları içerecek şekilde filtreler :0:

$> find . -iname '*.phtml' -exec grep -H -E -o -c 'new Mustache' {} \; | grep :0$

./app/MyApp/Customer/View/Account/quickcodemanagestore.phtml:0
./app/MyApp/Customer/View/Account/studio.phtml:0
./app/MyApp/Customer/View/Account/classadd.phtml:0
./app/MyApp/Customer/View/Account/orders-trade.phtml:0

İkinci boru sed 's/..$//'her satırın son iki karakterini sıyırıp sadece dosya yollarını bırakır.

$> find . -iname '*.phtml' -exec grep -H -E -o -c 'new Mustache' {} \; | grep :0$ | sed 's/..$//'

./app/MyApp/Customer/View/Account/quickcodemanagestore.phtml
./app/MyApp/Customer/View/Account/studio.phtml
./app/MyApp/Customer/View/Account/classadd.phtml
./app/MyApp/Customer/View/Account/orders-trade.phtml

3

Git kullanıyorsanız, izlenen tüm dosyaları arar:

git grep -L "foo"

Eğer açık globbing ** alt dizin varsa ve siz izlenen dosyaların bir alt kümesinde arama yapabilirsiniz ( shopt -s globstar.bashrc içinde, bakınız bu ):

git grep -L "foo" -- **/*.cpp

1

Grep'imin herhangi bir -L seçeneği yok. Bunu başarmak için geçici bir çözüm buluyorum.

Fikirler:

  1. hak edilen dizeyi içeren tüm dosya adını bir txt1.txt dosyasına dökmek için.
  2. dizindeki tüm dosya adlarını bir txt2.txt dosyasına dökün.
  3. diff komutu ile 2 döküm dosyası arasındaki farkı oluşturabilir.

    grep 'foo' *.log | cut -c1-14 | uniq > txt1.txt
    grep * *.log | cut -c1-14 | uniq > txt2.txt
    diff txt1.txt txt2.txt | grep ">"
    

Komutları unutuyorum ama dosya adlarını boşaltmak yerine, aslında diffiki çıkış akışı arasında bir komut yapabilirsiniz (komutları parantezle çevrelendiğinizi ve orada da bir yerlerde bir köşeli parantez olduğunu düşünüyorum), eğer sistemleriniz destekliyorsa, sanırım soru, desteklemediği içingrep -L
Dexygen

1

find *20161109* -mtime -2|grep -vwE "(TRIGGER)"

Filtreyi "find" altında ve hariç tutma dizesini "grep -vwE" altında belirtebilirsiniz. Değiştirilmiş süreye de filtre uygulamanız gerekip gerekmediğini bulmak için mtime öğesini kullanın.


Bu bana dize olmadan tüm satırları gösteriyor gibi görünüyor, OP sadece dosya adlarını ister.
Ben Farmer

1

Hata raporunu aç

@Tukan tarafından yorumlandığı gibi, Ag için -L/ --files-without-matchesflag ile ilgili bir açık hata raporu var :

Hata raporunda çok az ilerleme olduğu için, hatanın çözülmediği sürece -Laşağıda belirtilen seçeneğe güvenilmemelidir . Bunun yerine bu konuda sunulan farklı yaklaşımları kullanın. Hata raporu için bir açıklamada bulunmak [benimki vurgu]:

Bu konuda herhangi bir güncelleme var mı? -Ldosyanın ilk satırındaki eşleşmeleri tamamen yok sayar. Bu, yakında düzeltilmeyecekse, etkin bir şekilde reklamı yapılan şekilde çalışmadığı için bayrak tamamen kaldırılmalıdır .


Silver Searcher - Ag (amaçlanan işlev - hata raporuna bakın)

Güçlü bir alternatif olarak grep, The Silver Searcher - Ag'yi kullanabilirsiniz :

Hız odaklı, ack benzeri bir kod arama aracı.

Baktığımızda man ag, -Lveya --files-without-matchesseçeneğini buluyoruz :

...

OPTIONS
    ...

    -L --files-without-matches
           Only print the names of files that don´t contain matches.

Yani, geçerli dizinden eşleşmeyen dosyaları özyinelemeli olarak aramak için foo:

ag -L foo

Yalnızca geçerli dizinde eşleşmeyen dosyaları aramak için özyineleme için foobelirtmeniz yeterlidir --depth=0:

ag -L foo --depth 0

Bu -Lhata nedeniyle zaman zaman başarısız olur - github.com/ggreer/the_silver_searcher/issues/238
tukan

@tukan bilgi istemi için teşekkürler. Cevabı güncelledim; yanıtı silmemek yerine hata ile ilgili bilgileri açmak.
dfri

1

grep'in -L seçeneği (örneğin IBM AIX) yoksa, grep ve shell'den başka bir alternatif yoksa başka bir alternatif:

for file in * ; do grep -q 'my_pattern' $file || echo $file ; done

-4
grep -irnw "filepath" -ve "pattern"

veya

grep -ve "pattern" < file

Yukarıdaki komut bize -v, aranan desenin tersini bulduğu için sonuç verecektir.


1
Bu, desen içermeyen çizgileri yazdırır. Yalnızca -ldosya adını yazdırma seçeneğini ekleyebilirsiniz ; ancak bu , kalıbı içermeyen herhangi bir satır içeren herhangi bir dosyanın adını yazdırmaya devam eder. Ben OP desen içeren herhangi bir satır içermeyen dosyaları bulmak istediğine inanıyorum.
Üçlü

Sağladığınız komut, "dosyayolu" içindeki dosyaları "desen" içermeyen tüm satırlarıyla listeler.
aprodan

-6

Aşağıdaki komut, "foo" alt dizesini içeren satırları filtrelemenize yardımcı olabilir.

cat file | grep -v "foo"

2
Herhangi bir satırda eşleşme içermeyen dosya adları değil, eşleşmeyen satırlar yazdırılır. Yaralanmaya hakaret eklemek için, işe yaramaz bir kullanım olarakcat .
Üçlü
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.