Próbuję znaleźć wszystkie pliki określonego typu i nie zawierające określonego ciągu. Próbuję o tym poradzić przesyłając polecenie find do grep -v
przykład:
find -type f -name '*.java' | xargs grep -v "something something"
To nie wydaje się działać. Wygląda na to, że zwraca wszystkie pliki znalezione przez polecenie find. To, co próbuję zrobić, to w zasadzie znaleźć wszystkie pliki .java, które pasują do określonej nazwy pliku (np. Kończą się na „Pb” jak w SessionPb.java) i które nie mają w sobie „rozszerzenia coś”.
Podejrzewam, że robię to źle. Jak więc zamiast tego powinno wyglądać polecenie?
Odpowiedzi:
Nie ma tu potrzeby
xargs
. Również trzeba użyćgrep
z-L
opcją (pliki bez match), bo w przeciwnym razie będzie to wyjście zawartość pliku zamiast jego nazwy, jak w przykładzie.źródło
-L
już ma negocjacje, ponieważ to znaczyfiles _without_ match
. Dlatego nie potrzebujesz-v
tutaj opcji.find -exec \+
ktoś pisze mi, że o wiele lepiej jest używać xargs. dlaczego nikt nie patrzy na człowieka przed napisaniem komentarza? (:-exec ... {} \+
nie jest równoważny zxargs
. Przeczytaj dokumentację findutils! (Ciężko nad tym pracowałem!)xargs
przetwarza dane wejściowe i oddziela argumenty na spacji. Cytaty są również specjalne (domyślnie) dlaxargs
. Żadna z tych rzeczy nie jest prawdziwa-exec ... {} +
. Stare wersjexargs
uważały podkreślenie za wskaźnik EOF, ale już tak nie jest.Prawie masz to naprawdę ...
Kropka '.' mówi, żeby zacząć od tego miejsca. (twoje implikuje to ... ale nigdy nie zakładaj).
-iname używa wyszukiwania bez rozróżniania wielkości liter, na wszelki wypadek (lub po prostu nie na wielkość liter).
-print0 wysyła nazwy plików do xargs ze znakiem końcowym \ x00, co zapobiega problemom z nazwami plików zawierającymi spacje.
„-0” na xargs mówi, że oczekuje nazw plików kończących się na \ x00 zamiast zwrotów.
i twoje polecenie grep ...
Prawie to mam.
EDYTOWAĆ::
Z twojej aktualizacji:
powinno pomóc. (Dodano -L z odpowiedzi @ rush, dobra robota)
Rozumiem, że twój grep potrzebuje albo opcji „-i”, albo by był mniej wyraźny.
Spróbuj wykonać polecenie w częściach ... czy WYJŚCIE nazwy plików wyjściowych wydają się prawidłowe?
Jeśli tak, oznacza to, że problem prawdopodobnie nie pasuje do wzorca wyszukiwania grep (błąd pisowni? To się zdarza!) Lub po prostu nie ma żadnych dopasowań.
Absolutnie najgorszy przypadek:
wykona dużo więcej pracy, szukając wszystkiego, ale powinien dać ci pewien efekt.
źródło
xargs -0 grep -v "something something"
powinno byćxargs -0 grep -v "something something" /dev/null
inaczej, otrzymasz dziwne wyniki, gdy find nie utworzy pasujących plików.Komputer jest komputerem: robi to, co mu kazałeś, zamiast tego, co chciałeś.
grep -v "something something"
wypisuje wszystkie linie, które nie zawierająsomething something
. Na przykład drukuje dwie linie spośród następujących trzech:Aby wydrukować pliki, które
extends SomethingSomething
nigdzie nie zawierają , użyj-L
opcji:Niektóre wersje grep nie mają tej
-L
opcji (nie jest to określone przez POSIX ). Jeśli twój nie, niech nic nie wydrukuje i użyj kodu powrotu, aby powłoka wywołująca zrobiła to, co powinna.Alternatywnie użyj awk.
W systemie Linux lub Cygwin (lub innym systemie z GNU grep) nie musisz go używać
find
, ponieważgrep
może się powtarzać.Jeśli twoją powłoką jest ksh, bash lub zsh, możesz sprawić, aby powłoka dopasowała nazwę pliku. Uruchom bash jako
set -o globstar
pierwszy (możesz to umieścić w swoim~/.bashrc
).źródło
\s
to rozszerzenie GNU grep, które moim zdaniem jest synonimem[[:space:]]
.