Jak wykonać „grep” dla nazwy pliku zamiast zawartości pliku?

141

grep służy do przeszukiwania pliku w celu sprawdzenia, czy jakaś linia pasuje do danego wyrażenia regularnego. Jednak mam taką sytuację - chcę napisać wyrażenie regularne, które będzie pasowało do samej nazwy pliku (a nie do zawartości pliku). Uruchomię to z katalogu głównego systemu, aby znaleźć wszystkie pliki, które pasują do wyrażenia regularnego.

Na przykład, jeśli chcę znaleźć wszystkie pliki formularzy VB, które zaczynają się od „f” i kończą na .frm, użyję wyrażenia regularnego -

   "f[[:alnum:]]*\.frm"

Czy grep może to zrobić? Jeśli nie, czy istnieje narzędzie, które pozwoliłoby mi to zrobić? Dzięki.

CodeBlue
źródło

Odpowiedzi:

125

W tym przypadku musisz użyć findzamiast grep.

Możesz także używać findw połączeniu z greplub egrep:

$ find | grep "f[[:alnum:]]\.frm"
Pablo Santa Cruz
źródło
12
To jest niepotrzebne. Find ma tę funkcję wbudowaną w -regexopcję.
whereswalden
6
jest to niepotrzebne, ale grep obsługuje wyrażenia regularne perl, podczas gdy find nie.
Dan
3
Nie, możesz użyć grep. O wiele łatwiejsze niż używanie funkcji znajdowania Dodaj przełącznik „-rl”, a przeszuka on nazwę pliku zamiast pliku. Zobacz mój post poniżej.
RM
@ alpha_989, powiedziałem, że grep to obsługuje, co robi: gnu.org/software/grep/manual/html_node/ ... punkt jest potokiem do grepa jest potrzebny tylko wtedy, gdy potrzebujesz pcre. whereswalden ma właściwą odpowiedź
Dan
64

Przykład

find <path> -name *FileName*

Z instrukcji:

wzorzec find -name

Baza nazwy pliku (ścieżka z usuniętymi wiodącymi katalogami) pasuje do wzorca powłoki. Ponieważ wiodące katalogi są usuwane, nazwy plików rozważanych za dopasowanie z -name nigdy nie będą zawierać ukośnika, więc „-name a / b” nigdy nie będzie do niczego pasować (prawdopodobnie trzeba zamiast tego użyć -path). Metaznaki („*”, „?” I „[]”) odpowiadają „”. na początku nazwy bazowej (jest to zmiana w find-utils-4.2.2; zobacz sekcję ZGODNOŚĆ ZE STANDARDAMI poniżej). Aby zignorować katalog i znajdujące się w nim pliki, użyj -prune; zobacz przykład w opisie -path. Szelki nie są rozpoznawane jako wyjątkowe, pomimo faktu, że niektóre powłoki, w tym Bash, nadają szelki o specjalnym znaczeniu we wzorach muszli. Dopasowywanie nazw plików odbywa się za pomocą funkcji bibliotecznej fnmatch (3). Nie zapomnij ująć wzorca w cudzysłów, aby chronić go przed rozszerzaniem przez powłokę.

javaPlease42
źródło
3
Uważam, że ta odpowiedź jest najbardziej przydatna. Dodałem kilka dodatkowych opcji: find . -maxdepth 1 -name "*filename*" -print
JSON C11
47

Jak powiedział Pablo, musisz użyć findzamiast grep, ale nie ma potrzeby, aby to findzrobić grep. findma wbudowaną funkcjonalność:

find . -regex 'f[[:alnum:]]\.frm'

findto bardzo potężny program do wyszukiwania plików według nazwy i obsługuje wyszukiwanie według typu pliku, ograniczanie głębokości, łączenie różnych wyszukiwanych terminów z operacjami logicznymi oraz wykonywanie dowolnych poleceń na znalezionych plikach. Więcej informacji można znaleźć na stronie podręcznika wyszukiwania .

whereswalden
źródło
1
Dodałbym bardzo przydatną funkcję wyszukiwania według daty z -mtimei-mmin
Johnride
1
Ponadto przełącznik -regex dopasowuje całą ścieżkę. Aby przykład działał, należy dodać. * Na początku wyrażenia regularnego.
tumasgiu
18

Możesz znaleźć pełną ścieżkę do pliku używając grep, po prostu potokuj wyjście tree

tree -f | grep filename

Oto funkcja, którą możesz umieścić w swoim .bash_profile lub .bashrc

findfile(){ tree -f | grep $1; } # $1 = filename, -f is full path
jasonleonhard
źródło
-f jest opcjonalne.
jasonleonhard
10
find -iname "file_name"

Syntax :-
find -type type_descriptor file_name_here

type_descriptor typy: -

f: zwykły plik

d: katalog

l: dowiązanie symboliczne

c: urządzenia znakowe

b: urządzenia blokowe

Sireesh Yarlagadda
źródło
1
Nie mogę użyć nazwy pliku po -type typedescriptorsamym. Czy to pomyłka?
Allan Nørgaard
5

Możesz też:

tree | grep filename

Powoduje to przesyłanie danych wyjściowych polecenia tree do grep w celu wyszukiwania. To powie ci tylko, czy plik istnieje.

caylus
źródło
3

Najłatwiej jest

find . | grep test

tutaj find wypisze rekursywnie wszystkie pliki w (.), czyli bieżącym katalogu. A potem jest to po prostu zwykłe grep. pojawią się wszystkie pliki o nazwie „test”.

możesz grać z grep zgodnie z wymaganiami. Uwaga: ponieważ grep jest ogólną klasyfikacją ciągów, może skutkować nie tylko nazwami plików. ale jeśli ścieżka ma katalog („/xyz_test_123/other.txt”) również pojawi się w zestawie wyników. Twoje zdrowie

sachyy
źródło
To znajdzie wszystko, co ma w ścieżce słowo „test”, np ./foo/bar/latest/fred.txt.
Paul R
O. Ten, o którym nie pomyślałem. Dziękuję za wspomnienie.
sachyy
0

Nie, grep działa dobrze w tym przypadku:

 grep -rl "filename" [starting point]

 grep -rL "not in filename"
RM
źródło
2
Wyszukuje w zawartości pliku „nazwa pliku”, a następnie wyświetla nazwy plików z dopasowaniami. OP chce dopasować nazwy plików, a nie zawartość pliku.
Matthew
2
Zgoda, to nie wyszukuje nazw plików, po prostu wypisuje nazwy plików, do których została znaleziona treść . Znacząco źle zrozumiałeś obie opcje -li -L.
Prometheus
-1

Również dla wielu plików.

tree /path/to/directory/ | grep -i "file1 \| file2 \| file3"
DimiDak
źródło