Używanie `find` dla wielu rozszerzeń plików

16

Korzystam z następującego polecenia do zliczania wierszy tekstu w plikach JAVA:

find . -name '*.java' | xargs wc -l

Jak mogę zmodyfikować findparametry polecenia, aby pasowały do ​​więcej niż jednego rozszerzenia pliku? Na przykład chciałbym użyć powyższej operacji dla plików CPP, C i H.

Xavier
źródło
To pytanie dotyczy w rzeczywistości findpolecenia, ponieważ właśnie tam szukasz pasujących plików.
iglvzx
1
Również użyć albo find -print0 | xargs -0wytworzenie lub nawet lepsze i prostsze: find . -name '*.cpp' -o -name '*.c' -o -name '*.h' -exec wc -l {} +. Pozwoli to uniknąć problemów z nazwami plików (puste miejsca, nowe wiersze itd.) I jest (bardzo) dobrym niestandardowym.
Daniel Andersson,

Odpowiedzi:

16

Użyj -oopcji dla LUB. Na przykład, byłoby to listy .cpp, .ca .hpliki:

find . -name \*.cpp -o -name \*.c -o -name \*.h
JOTN
źródło
Ach Że *nie musi już być uciekł jeśli sformatowany jako kod. Całkowicie przeoczyłem to. :)
iglvzx
Tak, zajęło to trzy edycje dwóch osób, ale mamy to.
JOTN
2
Nie działało to dla mnie na OSX (pasowało tylko nazwisko * .ext) - musiałem użyć nawiasów, jak sugeruje @smokinguns poniżej.
Gilead
2

Musisz użyć opcji -o. Na przykład poniższe oświadczenie znajduje wszystkie pliki png, jpg i gif w folderze.

find . \( -iname \*.png -o -iname \*.jpg -o -iname \*.gif \)

Używam opcji -iname, aby dopasowanie nie uwzględniało wielkości liter.

palenie tytoniu
źródło
1
iname nie jest dostępne we wszystkich wersjach find.
JOTN
1

Chociaż wszystkie odpowiedzi są mniej więcej takie same, nie uważam ich za czytelne przy użyciu wielu operatorów nazw i logicznych pomiędzy nimi.

Myślę, że może to być bardziej eleganckie rozwiązanie:

$ find . -type f | grep -E "\.java$|\.cpp$|\.c$"

Zerwijmy to

  • find . znajdzie wszystkie pliki rekurencyjnie w bieżącej ścieżce (w razie potrzeby zmień inną ścieżkę)
  • -type fzawęża wyszukiwanie tylko do plików (niezbyt dużego przyrostu prędkości, ale nadal ...)
  • | grep -EUżyłem tego, aby uzyskać rozpoznawanie grep lub ( |) operatora w systemie Mac OS X, który używa grep FreeBSD , GNU grep tego nie potrzebuje (sprawdź w manpliku).
  • "\.java$|\.cpp$|\.c$"wyrażenie regularne, które zawiera pliki, których końce nazwa z .java, .cppi .c(te dodać Cię potrzebujesz)

Następnie możesz przesłać wynikową listę do dalszego przetwarzania, np

$ find . -type f | grep -E "\.java$|\.cpp$|\.c$" | xargs sed -i '' $'/s/\r$//'

Ten przykład usuwa CRLFzakończenie linii DOS / Windows dla OS X / Linux LF(jest to również sedskładnia OS X , sprawdź specyfikację swojej wersji).

MacMladen
źródło
Chciałem znaleźć wszystkie typy plików wideo przy użyciu 25 różnych parametrów dopasowania rozszerzenia. To było jedyne podejście, które działało dla mnie. (Ubuntu 14.04 LTS)
Starszy Geek
0

Posługiwać się

find path/to/dir -name "*.ext1" -o -name "*.ext2"

Wyjaśnienie

  1. Pierwszy parametr to katalog, który chcesz przeszukać.
  2. Domyślnie findrekursja.
  3. -oOznacza -or. Powyżej oznacza poszukiwanie tego symbolu wieloznacznego LUB tego. Jeśli masz tylko jeden wzór, nie ma takiej potrzeby -o.
  4. Cytaty wokół wzoru wieloznacznego są wymagane.
Shital Shah
źródło