Jak znaleźć pliki w bieżącym katalogu, które nie zawierają słowa foo(za pomocą grep)?
Jak znaleźć pliki w bieżącym katalogu, które nie zawierają słowa foo(za pomocą grep)?
Odpowiedzi:
Jeśli twój grep ma opcję -L(lub --files-without-match):
$ grep -L "foo" *
GREP_OPTIONS='--exclude-dir=.svn --exclude-dir=.git': ^)
-rLzamiast, -Laby dopasować podkatalogi
grep -L 'foo' -- *Standardowo polecenia wymagające długich opcji --wskazują, że po tym punkcie nie ma już żadnych opcji.
Spójrz na ack. Robi .svnwykluczenia dla Ciebie automatycznie, daje Perl wyrażeń regularnych, i jest prosty do pobrania z jednego programu Perl.
Odpowiednikiem tego, czego szukasz, powinno być ack:
ack -L foo
Możesz to zrobić tylko z grep (bez znalezienia).
grep -riL "foo" .
To jest wyjaśnienie zastosowanych parametrów grep
-L, --files-without-match
each file processed.
-R, -r, --recursive
Recursively search subdirectories listed.
-i, --ignore-case
Perform case insensitive matching.
Jeśli użyjesz l(małe litery) otrzymasz odwrotnie (pliki z dopasowaniami)
-l, --files-with-matches
Only the names of files containing selected lines are written
Następujące polecenie daje mi wszystkie pliki, które nie zawierają wzorca foo:
find . -not -ipath '.*svn*' -exec grep -H -E -o -c "foo" {} \; | grep 0
grep '0$'pasowałoby też do plików z wielokrotnością 10 linii! Na grep ':0$'końcu musisz sprawdzić wyraźne „: 0” na końcu linii. Otrzymasz wtedy tylko pliki z dopasowanymi zerami linii.
Następujące polecenie wyklucza potrzebę wyszukiwania przez filtrowanie svnfolderów za pomocą drugiego grep.
grep -rL "foo" ./* | grep -v "\.svn"
Będziesz potrzebować:
find . -not -ipath '.*svn*' -exec grep -H -E -o -c "foo" {} \; | grep :0\$
Problem
Muszę przefakturować duży projekt, który używa .phtmlplików do pisania HTML przy użyciu wbudowanego kodu PHP. Chcę zamiast tego użyć szablonów wąsów . Chcę znaleźć wszelkie .phtmlgiles, które nie zawierają łańcucha, new Mustacheponieważ nadal wymagają przepisania.
Rozwiązanie
find . -iname '*.phtml' -exec grep -H -E -o -c 'new Mustache' {} \; | grep :0$ | sed 's/..$//'
Wyjaśnienie
Przed rurami:
Odnaleźć
find . Znajdź pliki rekurencyjnie, zaczynając od tego katalogu
-iname '*.phtml'Nazwa pliku musi zawierać .phtml(i czyni to bez rozróżniania wielkości liter)
-exec 'grep -H -E -o -c 'new Mustache' {}'Uruchom greppolecenie na każdej ze zgodnych ścieżek
Grep
-H Zawsze drukuj nagłówki plików z wierszami wyjściowymi.
-E Interpretuj wzorzec jako rozszerzone wyrażenie regularne (tj. Wymuś, aby grep zachowywał się jak egrep).
-o Drukuje tylko pasującą część linii.
-c Tylko liczba wybranych wierszy jest zapisywana na standardowe wyjście.
To da mi listę wszystkich ścieżek plików kończących się na .phtml, wraz z liczbą przypadków, w których łańcuch new Mustachewystępuje w każdej z nich.
$> 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
Pierwsza rura grep :0$filtruje tę listę, aby uwzględnić tylko linie kończące się na :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
Druga rura sed 's/..$//'usuwa ostatnie dwa znaki każdego wiersza, pozostawiając tylko ścieżki plików.
$> 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
Mój grep nie ma żadnej opcji -L. Znalazłem obejście, aby to osiągnąć.
Pomysły to:
zrób różnicę między plikiem 2 zrzutu za pomocą polecenia diff.
grep 'foo' *.log | cut -c1-14 | uniq > txt1.txt
grep * *.log | cut -c1-14 | uniq > txt2.txt
diff txt1.txt txt2.txt | grep ">"
diffpomiędzy dwoma strumieniami wyjściowymi (myślę, że otaczasz polecenia nawiasami, a gdzieś tam jest też nawias kątowy), jeśli twój system to obsługuje, tak myślę jest pytanie, ponieważ nie obsługujegrep -L
find *20161109* -mtime -2|grep -vwE "(TRIGGER)"
Możesz określić filtr pod „find”, a ciąg wykluczenia pod „grep -vwE”. Jeśli chcesz filtrować według zmodyfikowanego czasu, użyj mtime w find.
Jak skomentował @tukan, istnieje otwarty raport o błędzie dla Ag dotyczący flagi -L/ --files-without-matches:
Ponieważ postęp w zgłaszaniu błędów jest niewielki, nie należy polegać na-L opcji wymienionej poniżej , dopóki błąd nie zostanie rozwiązany. Zamiast tego użyj różnych podejść przedstawionych w tym wątku. Cytując komentarz do raportu o błędzie [moje podkreślenie]:
Wszelkie aktualizacje na ten temat?
-Lcałkowicie ignoruje dopasowania w pierwszym wierszu pliku. Wygląda na to, że jeśli nie zostanie to wkrótce naprawione, flaga powinna zostać całkowicie usunięta, ponieważ w rzeczywistości nie działa tak, jak reklamowano .
Jako potężną alternatywę grepmożesz użyć Srebrnego Poszukiwacza - Ag :
Narzędzie do wyszukiwania kodu podobne do ack z naciskiem na szybkość.
Patrząc na man ag, znajdujemy opcję -Llub --files-without-matches:
... OPTIONS ... -L --files-without-matches Only print the names of files that don´t contain matches.
To znaczy, aby rekurencyjnie wyszukiwać pliki, które nie pasują foo, z bieżącego katalogu:
ag -L foo
Aby przeszukać tylko bieżący katalog w poszukiwaniu plików, które nie pasują foo, po prostu określ --depth=0rekurencję:
ag -L foo --depth 0
-Lbłędu - github.com/ggreer/the_silver_searcher/issues/238
grep -irnw "filepath" -ve "pattern"
lub
grep -ve "pattern" < file
powyższe polecenie da nam wynik, ponieważ -v znajdzie odwrotność przeszukiwanego wzorca
-lopcję drukowania tylko nazwy pliku; ale nadal drukuje nazwy każdego pliku zawierającego dowolny wiersz, który nie zawiera wzorca. Wierzę, że OP chce znaleźć pliki, które nie zawierają żadnej linii zawierającej wzorzec.
Poniższe polecenie może pomóc w filtrowaniu wierszy zawierających podciąg „foo”.
cat file | grep -v "foo"
cat .