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'
: ^)
-rL
zamiast, -L
aby 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 .svn
wykluczenia 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 svn
folderó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 .phtml
plików do pisania HTML przy użyciu wbudowanego kodu PHP. Chcę zamiast tego użyć szablonów wąsów . Chcę znaleźć wszelkie .phtml
giles, które nie zawierają łańcucha, new Mustache
ponieważ 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 grep
polecenie 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 Mustache
wystę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 ">"
diff
pomię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?
-L
cał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ę grep
moż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ę -L
lub --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=0
rekurencję:
ag -L foo --depth 0
-L
błę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
-l
opcję 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
.