Boru grep -v içine bulmak


18

Belirli bir tür ve belirli bir dize içermeyen tüm dosyaları bulmaya çalışıyorum. Ben boru ile grep -v bulmak bulmak için çalışıyorum

misal:

find -type f -name '*.java' | xargs grep -v "something something"

Bu işe yaramıyor gibi görünüyor. Sadece find komutunun bulduğu tüm dosyaları döndürüyor gibi görünüyor. Ne yapmaya çalışıyorum temelde (örneğin SessionPb.java 'Pb' ile biter) belirli bir dosya adıyla eşleşen ve içinde bir 'SomethingSomething genişletir "yok tüm .java dosyaları bulmaktır.

Şüphem yanlış yaptığım. Peki bunun yerine komut nasıl görünmeli?


işe yaramadığını düşündüren şeyleri ekleyebilirsiniz. belki grep ifadeniz çok açık? büyük / küçük harf duyarsızlığı için bir '-i' mi gerekiyor? Aşağıdaki cevabımı da görün ...
lornix

Yanıtlar:


21

Burada gerek xargsyok. Ayrıca kullanmak gerekir grepile -Laksi neden seçeneğiyle (maçın olmadan dosyaları) çıktısı verecektir sizin örnekte olduğu gibi ismi yerine dosya içeriğine sahiptir.

find . -type f -iname "*.java" -exec grep -L "something somethin" {} \+

1
-Lzaten müzakere var, çünkü bu demektir files _without_ match. Bu nedenle -vburada seçeneğe ihtiyacınız yok.
acele

3
sonunda ekstra + ile değil.
lynxlynxlynx

2
@ user946850 Ne zaman find -exec \+birisi yazsam bana xargs kullanmanın çok daha iyi olduğunu yazıyor. Yorum yazmadan önce neden kimse erkek gibi görünmüyor? (:
rush

5
@ user946850 -exec ... {} \+ile eşdeğer değildir xargs. Lütfen findutils belgelerini okuyun! (Üzerinde çok çalıştım!)
James Youngman

2
@ user946850 evet. Farklardan biri, (varsayılan olarak) xargsgirdisini işleyip beyaz boşluktaki bağımsız değişkenleri ayırmasıdır. Tırnak işaretleri de (varsayılan olarak) için özeldir xargs. Bunların hiçbiri için geçerli değil -exec ... {} +. Eski sürümleri xargsalt çizgiyi EOF göstergesi olarak değerlendiriyordu, ancak artık böyle değil.
James Youngman

7

Neredeyse tamamladın ...

find . -type f -iname "*.java" -print0 | xargs -0 grep -v "something something"

Nokta '.' buradan başlamasını söylüyor. (sizinki bunu ima ediyor ama asla varsaymayın).

-iname , büyük / küçük harfe duyarlı olmayan arama kullanır.
-print0 xargs sonda \ x00 karakteri olan dosya adları gönderir, bu da dosya adlarında boşluk bulunan sorunları önler.

xargs üzerindeki '-0', dosya adlarının döndürme yerine \ x00 ile bitmesini beklediğini söylüyor.

ve grep komutunuz ...

Hemen hemen anladım.


DÜZENLE::

Güncellemenizden:

find . -type f -iname "*pb.java" -print0 | xargs -0 grep -iL "something"

yardım etmelisin. (@ Rush'ın cevabından -L eklendi, iyi iş)

Grep'inizin '-i' seçeneğine ya da daha az açık olması gerektiği fikrini alıyorum.

Komutu parçalar halinde deneyin ... BU düzgün görünen dosya adları veriyor mu?

find . -type f -iname "*pb.java"

Öyleyse, sorununuz büyük olasılıkla grep arama modeliniz eşleşmiyor (yazım hatası mı? Oluyor!) Veya herhangi bir eşleşme yok.

Mutlak en kötü durum:

grep -riL "something" *

her şeyi aramak çok daha fazla iş yapar, ancak size bazı çıktılar vermelidir.


Değişikliklerinizi denedim ve hala beklediğim sonucu alamıyorum. Sorunu daha açık hale getirmek için güncellemeyi deneyeceğim.
Hyangelo

Sorunun yazarı sadece dosya adları bulmak istiyorsa, grep 'grep -l -v' olmamalı mı?
Bruce Ediger

* .java dosyalarındaki belirli içerikleri arıyor
lornix

xargs -0 grep -v "something something"olmalıdır xargs -0 grep -v "something something" /dev/nullbulmak eşleşen dosyaları üretir zaman aksi takdirde garip sonuçlar alırsınız.
James Youngman

{Grin} evet, orada bir yerlerde mantık tamamen kıllı oldu. Başınızı incitmek için ters bir yanlış mantık çoklu testi gibi bir şey yok.
lornix

4

Bilgisayar bir bilgisayar olmak istiyor: Yapmasını istediğiniz şey yerine söylediğiniz şeyi yapıyor.

grep -v "something something"içermeyen tüm satırları yazdırır something something. Örneğin, aşağıdaki üç arasında iki satır yazdırır:

hello world
this is something something
something else

Hiçbir extends SomethingSomethingyerde bulunmayan dosyaları yazdırmak için şu -Lseçeneği kullanın:

grep -L -E 'extends[[:space:]]+SomethingSomething' FILENAME…

Bazı grep sürümlerinde -Lseçenek yoktur ( POSIX tarafından belirtilmez ). Sizinkini almazsanız, hiçbir şey yazdırmayın ve arama kabuğunun bunun yerine ne yapması gerektiğini yapmak için dönüş kodunu kullanın.

grep -q -E 'extends[[:space:]]+SomethingSomething' FILENAME ||
echo "$FILENAME"

Alternatif olarak awk kullanın.

awk '
    FNR == 1 && NR != 1 && !found { print fn }
    FNR == 1 { fn = FILENAME; found = 0; }
    /extends[[:space:]]+SomethingSomething/ { found = 1 }
    END { if (fn != "" && !found) print fn }
'

Linux veya Cygwin'de (veya GNU grep'e sahip başka bir sistemde), tekrarlama yeteneğine sahip olduğu findgibi kullanmanıza gerek grepyoktur.

grep -R --include='*.java' -L -E 'extends[[:space:]]+SomethingSomething'

Kabuğunuz ksh veya bash veya zsh ise, kabuğun dosya adı eşleşmesini yapmasını sağlayabilirsiniz. set -o globstarÖnce bash, önce koş (bunu senin içine koyabilirsin ~/.bashrc).

grep -L -E 'extends[[:space:]]+SomethingSomething' **/*.java

Vay canına, bu daha da iyi. Anlayabildiğim kadarıyla işe yarayan 'extends (/ s) + SomethingSomething' kullanıyordum. Genişletilmiş Sözdizimi sürümünde belirtilen sözdiziminde herhangi bir fark var mı?
Hyangelo

@Hyangelo \s, eşanlamlı olduğunu düşündüğüm bir GNU grep uzantısıdır [[:space:]].
Gilles 'SO- kötü olmayı bırak'
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.