Příkaz find se používá pro vyhledávání souborů a adresářů v příkazovém řádku Linuxu.
Najít je jedním z nejvýkonnějších a často používaných příkazů. Je to také jeden z nejrozsáhlejších příkazů s více než 50 možnostmi, a proto je trochu matoucí, zvláště když je spárován s příkazem exec nebo xargs.
Pro správce systému nebo vývojáře softwaru je nemožné vyhnout se příkazu find při práci na příkazovém řádku. Místo toho, abyste se ho báli, měli byste přijmout jeho sílu.
Budu diskutovat o některých nejběžnějších příkladech příkazu find, který pravděpodobně použijete. Ale předtím vám dovolte, abych vám ukázal jeho syntaxi a jak ji používat.
Najít příkaz v Linuxu
Obecná syntaxe příkazu find je:
find [directory to search] [options] [expression]
Vše v hranatých závorkách [] je volitelné. To znamená, že můžete spustit find
příkaz bez jakýchkoli voleb a argumentů. Vypíše pouze všechny soubory a adresáře v aktuálním umístění. To není moc užitečné, že?
Podívejme se na to podrobněji:
directory to search
je v podstatě místo, odkud chcete začít hledat. Ve výchozím nastavení je vyhledávání rekurzivní a začíná z vaší aktuální polohy.options
určete typ vyhledávání, ať už podle názvu, podle typu, podle času změny atd. Zde je možných více než 50 možností.expression
umožňuje zadat hledaný výraz. Pokud chcete najít soubor podle názvu, výraz je název souboru. Pokud chcete najít soubory s názvem odpovídajícím vzoru, zadejte výraz ve vzoru.
Uvedu jednoduchý příklad:
find . -type f -name myfile
Tento příkaz spustí vyhledávání v aktuálním adresáři a jeho podadresářích za účelem nalezení souboru (ne adresáře) s názvem myfile
. Možnost -type f
požádá o vyhledání pouze souborů. Jediná tečka .
znamená aktuální adresář.
Podívejme se na několik praktických příkladů příkazu find.
Najít soubory a adresáře podle názvu
Soubory a adresáře můžete vyhledávat podle názvu:
find . -name SEARCH_NAME
Protože není zmíněn žádný typ souboru, vyhledává soubory i adresáře s daným názvem.
Níže uvedený příklad najde soubor i adresář s názvem mystuff:
[email protected]:~/Examples$ find -name mystuff
./new/mystuff
./mystuff
Najít pouze soubory nebo pouze adresáře
Pokud chcete hledat pouze soubory, zadejte typ souboru -f:
find . -type f -iname SEARCH_NAME
Na pořadí typu a názvu nezáleží. Vezměte předchozí příklad a vyhledejte pouze soubory:
[email protected]:~/Examples$ find -type f -name mystuff
./mystuff
Pokud chcete hledat pouze adresáře, zadejte typ -d:
find . -type d -name SEARCH_NAME
V předchozím souboru vyhledejte pouze adresáře:
[email protected]:~/Examples$ find -type d -name mystuff
./new/mystuff
Spustit vyhledávání bez rozlišení malých a velkých písmen
Ve výchozím nastavení příkaz find rozlišuje malá a velká písmena. Pomocí -iname
můžete spustit vyhledávání bez ohledu na velikost písmen s daným jménem místo -name
.
find . -type f -iname SEARCH_NAME
Můžete jej použít s type d
také.
[email protected]:~/Examples$ find -iname mystuff
./new/mystuff
./MyStuff
./mystuff
Snímek obrazovky s výše uvedenými třemi příklady:
Vyhledat soubory podle jejich přípony (důležité)
Jedním z nejběžnějších použití příkazu find je vyhledání souborů určitého typu nebo bych měl říci konkrétní přípony.
Řekněme například, že chcete vyhledat všechny soubory C++ v aktuálních adresářích. Soubory C++ končí příponou .cpp, takže v nich můžete vyhledávat takto:
find . -type f -name "*.cpp"
Tímto způsobem řeknete příkazu find, aby hledal type file
a s názvy, které končí .cpp
.
[email protected]:~$ find . -type f -name "*.cpp"
./file.cpp
./.cargo/registry/src/github.com-1ecc6299db9ec823/libz-sys-1.1.3/src/zlib/contrib/iostream2/zstream_test.cpp
./.cargo/registry/src/github.com-1ecc6299db9ec823/libz-sys-1.1.3/src/zlib/contrib/iostream/test.cpp
./.cargo/registry/src/github.com-1ecc6299db9ec823/libz-sys-1.1.3/src/zlib/contrib/iostream/zfstream.cpp
Při použití příkazu find vždy uveďte hledaný výraz do dvojitých uvozovek. Proč doporučuji používat u hledaného výrazu dvojité nebo jednoduché uvozovky? Protože pokud to neuděláte, shell rozšíří zástupný znak.
Pokud hledaný výraz neuzavřete do uvozovek:
find . -type f -name *.cpp
Váš shell rozbalí *.cpp a nahradí jej všemi soubory v aktuálním adresáři, jejichž názvy končí na .cpp.
To by mohlo fungovat, pokud existuje pouze jeden soubor, ale pokud jich je více, váš shell si bude stěžovat na nesprávnou syntaxi.
Ve výše uvedeném příkladu je pouze jeden soubor cpp, a proto když se příkaz rozšíří na find . -type f -name file.cpp
, funguje to, protože file.cpp
stále funguje jako hledaný výraz.
Ale ve stejném adresáři jsou dva soubory .txt, a proto když se příkaz rozšíří na find . -type f -name another.txt new.txt
, stěžuje si, protože nyní existuje více než jeden hledaný výraz.
To je důvod, proč byste měli hledaný výraz vždy zabalit do dvojitých uvozovek.
Vyhledat více souborů s více příponami (nebo podmínkou)
Výše uvedený příkaz hledal soubory s danou příponou. Co když chcete hledat soubory s různými příponami?
Místo toho, abyste spouštěli příkaz find vícekrát, spusťte jej jednou pomocí -o
možnost, která funguje jako logická podmínka NEBO:
find . -type f -name "*.cpp" -o -name "*.txt"
Zde je příklad:
[email protected]:~/Examples$ find . -type f -name "*.txt" -o -name "*.cpp"
./new.txt
./file.cpp
./new/new.txt
./new/dir2/another.txt
./new/dir1/new.txt
./another.txt
Vyhledat soubory v konkrétním adresáři
Dosud všechny příklady prováděly vyhledávání v aktuálním adresáři, protože jste zadali . v příkladech.
Tečku lze nahradit absolutní nebo relativní cestou k adresáři, takže můžete hledat soubory v určeném adresáři, aniž byste opustili své aktuální umístění.
[email protected]:~/Examples$ find ./new -name mystuff
./new/mystuff
Vyhledat soubory ve více adresářích
Pokud si myslíte, že by se požadovaný soubor (soubory) mohl nacházet na několika místech, nemusíte příkaz find spouštět vícekrát. Stačí zadat všechny cesty k adresáři, které se mají hledat, v příkazu find:
find ./location1 /second/location -type f -name "pattern"
Najít prázdné soubory a adresáře
-empty
volba umožňuje vyhledávat prázdné soubory a adresáře pomocí příkazu find.
Chcete-li najít všechny prázdné soubory a adresáře v aktuálním adresáři, použijte:
find . -empty
Můžete určit typ souboru, aby se hledaly pouze prázdné soubory nebo adresáře:
find . -empty -type f
Můžete to také zkombinovat s hledáním názvu souboru:
find . -empty -type f -name "*.cpp"
Najděte velké nebo malé soubory (hledejte podle velikosti souboru)
Velké soubory nebo malé soubory můžete najít na základě vyhledávání provedeného parametrem velikost. Toto funguje pouze se soubory, nikoli s adresáři.
Používáte -size
možnost s +N pro velikost větší než N a -N pro velikost menší než N.
Najít soubory o velikosti přesně 50 kB:
find . -size 50k
Chcete-li vyhledat soubory větší než 1 GB v aktuálním adresáři:
find . -size +1G
Chcete-li najít menší než 20 bajtů:
find . -size -20c
Chcete-li najít soubory větší než 100 MB, ale menší než 2 GB:
find . -size +100M -size -2G
Můžete také kombinovat vyhledávání velikosti s vyhledáváním podle názvu. Chcete-li například vyhledat všechny soubory s názvem končícím na .log, ale velikostí větší než 500 MB v kořenovém adresáři, můžete použít:
find / -size +500M -name "*.log"
Pro připomenutí:
c
:bajtůk
:kilobajtyM
:MegabajtyG
:Gigabajty
Najít nedávno upravené soubory (hledat podle času úpravy nebo vytvoření)
Znáte pojem mtime, atime a ctime, že?
- mtime:čas poslední úpravy souboru
- ctime:čas vytvoření souboru
- atime:čas posledního přístupu k souboru
Často se ocitnete v situacích, kdy budete chtít najít všechny nedávno upravené soubory. V takových případech pomáhá hledání podle upraveného času.
Chcete-li najít všechny soubory upravené do 3 dnů (3*24H), použijte:
find . -type f -mtime -3
Chcete-li najít všechny soubory vytvořené alespoň před 5 dny (5*24H), použijte:
find . -type f -ctime +5
Vím, že 24 hodin je obrovský časový rámec. Co když chcete vyhledat soubory, které byly upraveny jen před několika minutami? K tomu můžete použít mmin
, amin
a cmin
.
Chcete-li najít všechny soubory, které byly změněny za posledních 5 minut, použijte:
find . -type f -mmin -5
Můžete zadat horní a dolní limit spolu s názvem vyhledávání. Níže uvedený příkaz vyhledá všechny soubory .java, které byly změněny za posledních 20 až 30 minut.
find . -type f -mmin +20 -mmin -30 -name "*.java"
Najít soubory se specifickými oprávněními
Doufám, že jste obeznámeni s konceptem oprávnění souborů v Linuxu.
Příkaz find vám umožňuje vyhledávat soubory se specifickým oprávněním k souboru a režimem přístupu.
find -perm mode
Například pro nalezení všech souborů v režimu přístupu 777 v aktuálním adresáři;
find . -perm 777
Chcete-li najít všechny soubory s přístupem pro čtení a zápis pro všechny (přesná shoda, nebude se shodovat, pokud má soubor oprávnění ke spuštění pro všechny):
find . -perm a=r+w
Vyhledání souborů vlastněných uživatelem
Můžete také vyhledávat soubory na základě vlastnictví.
Chcete-li například najít soubory vlastněné uživatelem Johnem v aktuálním adresáři, použijte:
find . -type f -user John
Můžete jej také kombinovat s dalšími možnostmi, jako je velikost, čas a jméno:
find . -type f -user John -name "*.cpp"
Nehledat rekurzivně, hledat pouze v aktuálním adresáři
Ve výchozím nastavení vyhledává příkaz find ve všech podadresářích vašeho aktuálního umístění. Pokud si to nepřejete, můžete zadat hloubku vyhledávání na 1. To omezí vyhledávání pouze na aktuální adresář a vyloučí všechny podadresáře.
find . -maxdepth 1 -type f -name "*.txt"
Vyloučení adresáře z vyhledávání
pokud chcete z vyhledávání vyloučit adresář, můžete to udělat kombinací cesty, prořezávání a logického nebo.
find . -path "./directory_exclude/*" -prune -o -name SEARCH_NAME
Buďte opatrní s * v cestě k adresáři, -prune
za cestou a -o
po prořezávání.
Příkaz prune v podstatě žádá, aby se nepoužívala hodnota zadaná cestou. Prune se vždy používá s -o
abyste zajistili, že pravá strana podmínek bude vyhodnocena pouze pro adresáře, které nebyly oříznuty.
Provést akci na základě výsledků příkazů find (exec a xargs)
Doposud jste se naučili různé způsoby vyhledávání souborů na základě různých kritérií. To je dobré. Můžete to ale vylepšit provedením určitých akcí s výsledkem příkazu find.
Co takhle například najít soubory odpovídající určitému vzoru názvu a přejmenovat je všechny najednou nebo najít prázdné soubory a smazat je?
Víte, že přesměrování potrubí lze použít ke spojení výstupu jednoho příkazu se vstupem jiného příkazu. Ale to nebude fungovat s výstupem příkazu find, alespoň ne přímo.
Pokud chcete provést akci s výsledkem příkazu find, máte dvě možnosti:
- Použijte exec
- Použijte xargs
Použití funkce find a exec
Předpokládejme, že chcete dlouhý seznam (ls -l) prohledávaných souborů pomocí příkazu find. Zde je to, co používáte:
find . -type f -name "*.txt" -exec ls -l {} +
Zde je výstup:
[email protected]:~/Examples$ find . -type f -name "*.txt" -exec ls -l {} +
-rw-rw-r-- 1 abhishek abhishek 39 Oct 13 19:30 ./another.txt
-rw-rw-r-- 1 abhishek abhishek 35 Oct 13 15:36 ./new/dir1/new.txt
-rw-rw-r-- 1 abhishek abhishek 35 Oct 13 15:36 ./new/dir2/another.txt
-rw-rw-r-- 1 abhishek abhishek 35 Oct 13 18:51 ./new/mystuff/new.txt
-rwxrwxrwx 1 abhishek abhishek 35 Oct 13 15:37 ./new/new.txt
-rw-rw-r-- 1 abhishek abhishek 35 Oct 13 18:16 ./new.txt
Mnoho lidí zapomíná přidat {} +
na konci příkazu exec. Musíte jej použít a dbát na mezeru mezi {} a +.
{} je to, co odkazuje na výsledek příkazu find. Můžete si to představit jako {soubor 1, soubor 2, soubor 3}. +
znak se používá k ukončení příkazu exec.
Existuje také další konvence s exec:
find . -type f -name *.txt" -exec ls -l {} \;
Tady,; se používá místo znaménka +. Dodatečné \ před; se používá k escapování speciálního znaku;.
Výhoda {} +
spočívá v tom, že spouští méně příkazů jako ls -l file1 file2 file3
zatímco {} \;
spustí ls -l file1
, ls -l file2
atd.
Ale {} \;
má tu výhodu, že používá {}
více než jednou ve stejném příkazu exec. Například příkaz níže přejmenuje všechny nalezené soubory s příponou .old.
find . -type f -name *.txt" -exec mv {} {}.old \;
Použití xargs
Mnoho uživatelů Linuxu si na přesměrování potrubí zvykne. Tento příkaz exec s koncovým {} +
zdá se jim zastrašující.
Zde pomáhá xargs. Jednoduše analyzujete výstup příkazu find na příkaz xargs pomocí potrubí.
find . -type f -name *.txt" | xargs ls -l
Syntaxe se zdá mnohem jednodušší, že? Příkaz Xargs je také velmi výkonný. Můžete si o tom přečíst zde.
Kombinace find a grep
Nyní, když víte o kombinaci find s xargs a příkazem exec, můžete jej použít ke kombinaci find a grep.
Pro každého správce systému nebo vývojáře softwaru je hledání a grep jednou z nejběžnějších a přitom nejužitečnějších kombinací.
Pomocí funkce find vyhledáváte vzory názvů souborů a poté pomocí grep vyhledáte obsah v těchto souborech.
Chcete například vyhledat všechny soubory .txt, které obsahují výraz Alice. Zkombinujete find a grep takto:
find . -type f -name "*.txt" -exec grep -i alice {} +
Totéž lze dosáhnout také pomocí xargů:
find . -type f -name "*.txt" | xargs grep -i alice
Toto je samozřejmě nejjednodušší z příkladů, ale pokud znáte příkaz grep, můžete jej použít podle svých představ a potřeb.
Najdi toho je mnohem víc...
A není možné vypsat všechny možnosti a příklady příkazu find. Možnosti jsou nekonečné, ale když se seznámíte s příkazem find, můžete jej začít používat v různých situacích. Je opravdu na vás, jak zde zkombinujete logiku.
Doufám, že vám tyto příklady příkazu find budou užitečné. Pokud máte stále dotazy nebo návrhy na vylepšení tohoto článku, dejte mi prosím vědět v sekci komentářů.