Jak znaleźć plik z dowolnego katalogu

22

Próbuję wyszukać plik o nazwie Book1 .

W moim teście próbuję wyszukać wspomniany plik, aw tym teście nie wiem, gdzie ten plik się znajduje.

Próbowałem, find / -iname book1ale nie ma wyjścia.

Jak znaleźć plik o nazwie book1 przy użyciu wiersza polecenia, jeśli nie wiem, gdzie plik się znajduje?

EDYTOWAĆ:

Mój scenariusz jest opisany bardziej szczegółowo poniżej:

  1. Rozszerzenie pliku jest nieznane
  2. Dokładna nazwa (tj. Wielkie litery, cyfry itp.) Jest nieznana
  3. Lokalizacja pliku jest nieznana
Aspire27
źródło
2
Jeśli istnieje plik o nazwie Book1, który znajduje się w katalogu, który można odczytać, to find / -iname book1go znajdzie. Jesteś pewien, że tak jest Book1, a nie Book1.xyz?
Fox
Pełna nazwa pliku to Book1.gnumeric. Czy mówisz, że muszę podać całą nazwę pliku? Z jakiegoś powodu pomyślałem, dla tego konkretnego polecenia, że ​​wszystko, czego potrzebuję, to ogólna nazwa pliku. Mój test próbuje znaleźć plik, jeśli na przykład nie pamiętam rozszerzenia pliku i znam tylko nazwę pliku, którego szukam. Proszę doradź.
Aspire27
@don_crissti Gotowe. Zobacz wyżej Edytuj.
Aspire27
Miksujesz find i locate. locatejest hojny i znajdzie wszystko, co pasuje, o ile znajduje się w bazie danych, która jest zwykle aktualizowana codziennie. find, w tym przypadku szuka globu plików, rodzaju wzorca, którego byś użył ls. Prawdopodobnie masz na myśli iname '*book1*'. Zauważ, że wzorzec musi znajdować się w cudzysłowie, aby powłoka nie mogła go rozwinąć, zanim findgo zobaczy. Zauważ też, że findpodobnie jak wiele komend * nix, jest frustrująco cichy, gdy kończy się niepowodzeniem.
Manngo

Odpowiedzi:

31

Po pierwsze argumentem -inamejest wzór powłoki . Możesz przeczytać więcej o wzorach w instrukcji Bash . Istotą jest to, że findaby faktycznie znaleźć plik, nazwa pliku musi pasować do określonego wzorca. Aby book1dopasować ciąg znaków bez rozróżniania wielkości liter Book1.gnumeric, musisz dodać, *aby wyglądało to tak:

find / -iname 'book1*'

lub podaj pełną nazwę:

find / -iname 'Book1.gnumeric'

Po drugie, -inamepozwoli findzignorować sprawę nazwy pliku, więc jeśli określenie -iname book1to może również znaleźć Book1, bOok1itd. Jeśli masz pewność, że plik szukasz nazywa się Book1.gnumeric wtedy nie używać -iname, ale -namebędzie to szybciej:

find / -name 'Book1.gnumeric'

Po trzecie, pamiętaj o zacytowaniu wzoru, jak powiedziano w drugiej odpowiedzi .

I na koniec - czy jesteś pewien, że chcesz szukać pliku wszędzie w systemie? Możliwe, że plik, którego szukasz, znajduje się w twoim $HOMEkatalogu, jeśli pracowałeś nad tym lub skądś go pobrałeś. Znowu może to być znacznie szybsze.

EDYCJA :

Zauważyłem, że zredagowałeś swoje pytanie. Jeśli nie znasz pełnej nazwy pliku, wielkich liter i lokalizacji, powinieneś użyć czegoś takiego:

find / -iname 'book1*'

Sugeruję również umieszczenie 2>/dev/nullna końcu wiersza, aby ukryć wszystkie *permission denied*i inne błędy, które pojawią się, jeśli wywołasz findjako użytkownik inny niż root:

find / -iname 'book1*' 2>/dev/null

A jeśli masz pewność, że szukasz pojedynczego pliku, a w systemie jest tylko jeden plik, który spełnia kryteria, które możesz powiedzieć, findaby wyjść po znalezieniu pierwszego pasującego pliku:

find / -iname 'book1*' -print -quit 2>/dev/null
Arkadiusz Drabczyk
źródło
1
-inamenie jest przenośny
Gert van den Berg
6

Możesz spróbować wykonać locatepolecenie. Korzysta z bazy nazw plików, aby wyszukiwanie było szybsze.

Aby wyszukać wszystkie pasujące pliki *book1*i ignorować wielkość liter, możesz użyć

locate -i book1

jeśli chcesz wyszukać pliki zaczynające się od book1, musisz samodzielnie wykonać znak zastępczy:

locate -i 'book1*'

Jest znacznie szybszy niż find, ale jest tak aktualny, jak podczas ostatniej aktualizacji bazy danych.

James K.
źródło
5

Jeśli wiesz, że masz plik o nazwie book1.something, którego lokalizacja, dokładna wartość somethingi wzorzec wielkości liter nazwy pliku są nieznane:

find / -iname 'book1.*'

Jeśli wszystko, co wiesz na pewno, to że nazwa pliku zawiera słowo book, możesz wygenerować prawdopodobnie znacznie większą listę

find / -iname '*book*'

Argumentem -namejest wzór globu powłoki. W katalogu, w którym znajduje się plik, porównaj:

$ ls Book1
ls: cannot access 'Book1': No such file or directory
$ ls Book1.*
Book1.gnumeric

Jest to rodzaj wyszukiwania przeprowadzanego przez -name. Ta -inameopcja pozwala po prostu rozróżnić wielkość liter.

Lis
źródło
1

POSIXly,

LC_ALL=C find / -name '*[bB][oO][oO][kK]1*'

Zgłosi się ścieżki wszystkich plików, których nazwa zawiera book1(z dowolnej odmianie przypadku, ale tylko biorąc pod uwagę ASCII alfabecie łacińskim bokBOK, a nie wiele innych odmian jak w Unicode 𝗄, 𝚔, 𝘬, , , , i wszystkie ich odmiany ze znakami diakrytycznymi ...) w wszystkie katalogi, do których masz dostęp do odczytu.

Stéphane Chazelas
źródło
0

Do tego rodzaju zadań zawsze wykonuję: find / -iregex '.*Book1.*'

Ta forma zająłaby 3 punkty twojego scenariusza ( iregexjest to racjonalne wyrażenie bez rozróżniania wielkości liter, a wzorzec z .*obu stron pasowałby do każdej postaci przed i po ustalonym wzorcu Book1 - to oczywiście może dać ci więcej wyników niż to konieczne ale na pewno nie przegapisz pliku)

Główną różnicą: jeśli to możliwe, być bardziej restrykcyjne niż tylko za pomocą /, jak próbuje tylko /homeczy tak, w przeciwnym razie będzie zejść w niektórych katalogów, które nie są istotne ( /sys, /devitp ...)

Pamiętaj jednak, że obowiązują uprawnienia Unix: jeśli plik znajduje się w katalogu, do którego użytkownik uruchamiający findkomendę nie ma prawa dostępu (wykonania), findnie będzie mógł go tam znaleźć.

Patrick Mevzek
źródło
iregex nie będzie działał w miejscach takich jak Solaris (system operacyjny nie został określony) (i prawdopodobnie * BSD), jest to rozszerzenie GNU i nie jest częścią standardufind
Gert van den Berg
0

Silver Searcher to bardzo szybkie i wygodne narzędzie do wyszukiwania plików i treści.

Aby rozwiązać problem, polecenie srebrnego wyszukiwania będzie wyglądać tak ...

ag -g Book1

-g PATTERN Drukuj nazwy plików pasujące do WZORCA

qoomon
źródło
0

locate a jego warianty wydają się być szybką metodą.

# updatedb # run as root, possibly using sudo, e.g. sudo -b updatedb. If file is on the system for more than a day it should already be in the index and this can be skipped
$ locate -i book1

Jeśli lokalizacja nie jest dostępna, możesz findzamiast tego użyć . Zwykle jest znacznie wolniejszy, ale także znacznie bardziej precyzyjny.

Jeśli masz jedną partycję: (uruchom jako root, jeśli użytkownik może nie mieć dostępu do pliku)

$ find / -xdev -iname 'book1*' -print # If the iname extension to find is available
$ find / -xdev -print | grep -F -i /book1 # if iname is not available

Jeśli nie uwzględnisz -xdev findwyszukiwania rzeczy na innych partycjach, takich jak /proci /sys, które mają tendencję do zalewania ekranu błędami, szczególnie jeśli nie jesteś rootem. (Błędy można ukryć, dodając je 2> /dev/nullna końcu polecenia find (komentarz powinien zostać usunięty))

Jeśli masz wiele partycji i nie wiesz, na której z nich znajduje się plik, możesz uzyskać listę lsblk(w systemach operacyjnych Linux, parsowanie dfdanych wyjściowych jest opcją w przeciwnym razie) i podać je w pliku find: (root ponownie, jeśli nie wiem, czy możesz uzyskać dostęp do pliku)

$ find $(lsblk -O MOUNTPOINT -n | grep -F /) -xdev -iname 'book1*' -print # GNU-based OSes
$ find $(df -P|awk '$1 ~ /^\/dev/ {print $NF}') -xdev | grep -F -i book1 # Non-GNU based OSes.

(Jest to trochę niestabilne, jeśli któryś z punktów montowania ma spacje w środku) ( dfparametry mogą wymagać dostrajania. -P powoduje, że GNU dfdaje standardowe wyjście POSIX. Inne wersje mogą mieć inne parametry lub wymagać ich pominięcia. Przeczytaj stronę podręcznika)

Nie grep -Fobejmuje innych rzeczy zwróconych, takich jak partycje wymiany.

W wersji innej niż GNU awk znajduje urządzenia z /devpodłączeniem, zaczynając od, aby uzyskać prawdziwe systemy plików, a następnie drukuje ostatnie pole (mountpoint) z dfwyjścia.

Zakłada to również powłokę typu bourne ( kshi bashpowinna działać. Jeśli używasz cshwariantu, uruchom skryptowalną powłokę przed wypróbowaniem tego)

Gert van den Berg
źródło
Do greps może być nieco głośno, nauczyć się filtrować go lepiej (to nie powinno być potrzebne na przykładzie, ale jeśli jest coś bardziej powszechne, że jest poszukiwany, to greps musiałby strojenie, aby utrzymać poziom hałasu w dół)
Gert van den Berg
0

ag (srebrny wyszukiwarka) zapewnia bardzo szybkie wyszukiwanie w plikach, a także ma opcję wyszukiwania nazwy pliku:

>: time ag -g foo # uses heuristics to only look in desired locations
apps/vxy/src/assets/tree-content-pages/tree-page-bird/foo-illustration.jpg

real    0m0.884s
user    0m0.701s
sys     0m0.178s

>: time find . -name "*foo*"
./apps/ssr/dist/static/media/foo-illustration.jpg
./apps/vxy/dist/static/media/foo-illustration.jpg
./apps/vxy/src/assets/tree-content-pages/tree-page-bird/foo-illustration.jpg

real    0m29.744s
user    0m2.108s
sys     0m13.982s

>: time ag -ug foo # searching all files is still faster and simpler to use then find command
apps/ssr/dist/static/media/foo-illustration.jpg
apps/vxy/dist/static/media/foo-illustration.jpg
apps/vxy/src/assets/tree-content-pages/tree-page-bird/foo-illustration.jpg

real    0m16.698s
user    0m1.951s
sys     0m7.119s

Więc w moim przypadku użycia jest> 30 razy szybszy, jeśli plik nie jest plikiem ignorowanym przez ag.

tomtt
źródło