Příkaz find umožňuje uživatelům vyhledávat soubory a provádět s nimi akce. Je součástí balíčku „findutils“ a je dodáván se všemi distribucemi. Je vysoce flexibilní a umožňuje vám vyhledávat soubory a adresáře na základě různých podmínek. Volitelně vám také umožňuje provádět různé typy akcí s výsledky.
V tomto článku pochopíme, jak pracovat s příkazem find. Jeho použití také ilustrujeme na různých příkladech v tomto článku.
Úvod
Základní struktura příkazu find je taková:
find [paths] [expression] [actions]
Příkaz find používá řadu cest a hledá soubory a adresáře v každé cestě „rekurzivně“. Když tedy příkaz find narazí na adresář uvnitř dané cesty, hledá v něm další soubory a adresáře. Opět, pokud jsou uvnitř další adresáře, příkaz find se podívá i do nich. Tento proces pokračuje, dokud nevyhledá všechny položky v zadané cestě.
Ve výchozím nastavení příkaz find najde vše v adresáři. Pokud chcete některé z nich odfiltrovat na základě určitých kritérií, můžete k tomu zadat výraz.
Výchozí akcí je tisk všech výsledků. Můžete však také určit vlastní akci, kterou může příkaz find provést s výsledky.
Tyto pojmy budou jasnější, až si projdeme různé příklady uvedené dále v tomto článku.
Nalezení všech souborů a adresářů
Představte si, že chcete vypsat všechny adresáře a soubory pro danou cestu. Pokud například chcete vypsat obsah /usr/share
adresář, spusťte:
find /usr/share
Zobrazí se vám seznam souborů a adresářů, jak je znázorněno na obrázku níže. V závislosti na obsahu adresáře může být tento seznam velmi velký!
Pokud chcete vypsat obsah více adresářů, můžete to udělat takto:
find /usr/share /bin /usr/lib
Pokud chcete vypsat obsah aktuálního pracovního adresáře, použijte tečku (.
) jako cestu:
find .
Pokud neexistují žádné cesty, příkaz find předpokládá, že by měl pracovat s aktuálním adresářem. Takže můžete nechat .
a jednoduše použijte:
find
Vyhledání položek podle jejich názvu
Jak jsme již zmínili, výsledky příkazu find můžete filtrovat pomocí výrazů. V této části se naučíme, jak filtrovat položky podle jejich názvu.
Pokud chcete najít soubor nebo adresář s názvem NEWS.txt
uvnitř /usr
použijte adresář -name
přepněte takto:
find /usr -name NEWS.txt
-name
přepínač rozlišuje malá a velká písmena. Pokud neznáte přesnou velikost písmen položky, kterou hledáte, můžete použít -iname
přepínač, který nerozlišuje malá a velká písmena:
find /usr -iname news.txt
-name
a -iname
přepínače také přijímají „zástupné znaky“, což jsou speciální znaky, které fungují jako zástupné symboly. Existují dva zástupné znaky — ?
znak představuje jeden neznámý znak a *
znak představuje libovolný počet neznámých znaků (včetně nuly).
Pokud chcete použít zástupný znak, měli byste ponechat name
/iname
parametr v jednoduchých nebo dvojitých uvozovkách. Od *
a ?
znaky jsou také speciální znaky pro shell, jejich uvedení do uvozovek zajišťuje, že příkaz funguje správně.
Například, pokud musíte hledat všechny soubory a adresáře v /usr
které mají .txt
na konci jejich názvu můžete použít:
find /usr -name '*.txt'
Pokud chcete hledat soubory a adresáře se čtyřmi písmeny v názvu, spusťte:
find /usr -name '????'
Někdy můžete chtít porovnat úplnou cestu k souboru/adresáři místo pouhého shody názvu. V takové situaci můžete použít -path
přepínač. Řekněme například, že chcete najít všechny soubory a adresáře s .txt
na konci jejich jména, ale pouze pokud jsou v adresáři s názvem src
. V celé cestě tedy bude /src/
někde uprostřed a .txt
na konci. Příkaz tedy bude:
find /usr -path '*/src/*.txt'
Existuje také -ipath
switch, což je verze -path
bez rozlišení velkých a malých písmen .
Vyhledávání souborů nebo adresářů
Všechny příklady, které jsme dosud viděli, vracejí soubory a adresáře. Pokud však potřebujete hledat pouze soubory nebo adresáře, můžete použít -type
přepínač. Nejběžnější parametry -type
jsou:
-
f
:soubory -
d
:adresáře -
l
: symbolické odkazy
Chcete-li například najít všechny soubory v /usr
adresář, spusťte:
find /usr -type f
Můžete také kombinovat různé přepínače příkazu find. Chcete-li například najít všechny .txt
soubory v /usr
adresář, můžete použít:
find /usr -type f -name '*.txt'
Podobně k nalezení adresářů v /usr
které začínají na „python“, použijte:
find /usr -type d -name 'python*'
Hledání prázdných souborů
Příkaz find podporuje -empty
flag pro vyhledání souborů a adresářů, které jsou prázdné. Prázdný soubor je takový, který nemá žádný obsah, zatímco prázdný adresář je takový, který nemá žádné soubory ani podadresáře.
Pokud například chcete najít seznam prázdných adresářů ve svém domovském adresáři, můžete spustit:
find ~ -type d -empty
Negování shod
Příkaz find také umožňuje „negovat“ shodu. To je užitečné, když máme kritéria pro vyloučení z našeho vyhledávání.
Řekněme například, že chcete najít soubory v /usr
adresář, který nemá .txt
rozšíření. -name
můžete negovat přepněte přidáním vykřičníku (!
) před ním, jak je znázorněno:
find /usr -type f ! -name '*.txt'
Můžete také obrátit jakýkoli jiný přepínač. Pokud tedy chcete najít neprázdné adresáře ve vašem domovském adresáři, spusťte:
find /usr -type f ! -empty
Vyhledávání na základě vlastnictví
Příkaz find podporuje vyhledávání souborů a adresářů na základě informací o jejich vlastnictví.
Chcete-li najít soubory nebo adresáře, které patří konkrétnímu uživateli, můžete použít -user
přepínač. Například pokud chcete najít všechny soubory v systému, které patří uživateli booleanworld
, spustit:
find / -type f -user booleanworld
Místo uživatelského jména můžete ve výše uvedeném příkazu také použít ID uživatele. ID uživatele můžete vyhledat pomocí následujícího příkazu:
id -u <username>
Stejně tak -group
přepínač umožňuje vyhledávat soubory a adresáře, které patří do určité skupiny. Může také přijmout název skupiny nebo ID skupiny. ID skupiny uživatele můžete zobrazit pomocí následujícího příkazu:
id -g <username>
Vyhledávání souborů podle data a času
Někdy může být nutné hledat soubory v závislosti na tom, kdy byly zpřístupněny nebo upraveny. V systému Linux jsou k souboru přidruženy tři typy „času“:
- Čas úpravy :Naposledy, kdy byl obsah souboru upraven.
- Čas přístupu :Poslední čas, kdy byl soubor načten.
- Změnit čas :Naposledy, kdy byl soubor (buď jeho obsah nebo metadata, jako jsou oprávnění) upraven.
Chcete-li najít soubory na základě času úpravy, přístupu nebo změny, má příkaz find -mtime
, -atime
a -ctime
přepínače. Tyto přepínače umožňují filtrovat soubory podle počtu dní. Zde „den“ označuje období 24 hodin.
Pojďme pochopit, jak tyto příznaky používat. Pokud například použijete -mtime
, pak:
-
-mtime 2
:Soubor byl změněn před 2 dny (tj. za posledních 48 až 72 hodin). -
-mtime -2
:Soubor byl změněn před méně než 2 dny (tj. během posledních 48 hodin). -
-mtime +2
:Soubor byl změněn před více než 2 dny (tj. 3 nebo více dny, což znamená 72 hodin nebo později).
Chcete-li tedy najít soubory v /usr
které byly upraveny před dvěma dny, spusťte:
find /usr -type f -mtime 2
-atime
a -ctime
přepínače fungují úplně stejně jako -mtime
.
Pokud zjistíte, že den je příliš dlouhý, můžete také použít -mmin
, -amin
nebo -cmin
filtrovat za pár minut. Takže -amin +5
znamená soubory, které byly zpřístupněny před více než 5 minutami, -amin -5
znamená, že soubor byl změněn před méně než 5 minutami a tak dále.
Můžete použít mnoho těchto příznaků najednou. Pokud chcete najít soubory upravené před 2 dny a přístupné před 5 minutami, spusťte:
find /usr -type f -mtime 2 -amin 5
Můžete dokonce opakovat stejnou vlajku! Chcete-li například najít soubory upravené před 50 až 100 dny, použijte:
find /usr -type f -mtime +50 -mtime -100
Vyhledávání podle velikosti
Příkaz find má -size
přepnout, aby uživatelé mohli najít soubory na základě jejich velikosti. Protože pouze soubory mohou mít velikost souboru, při použití tohoto přepínače nebudou uvedeny žádné adresáře.
Abychom určili velikost souboru, vložíme číslo následované písmenem reprezentujícím jednotku. Můžete použít následující písmena:
-
c
:bajtů -
k
:kilobajty -
M
:megabajty -
G
:gigabajty
Kromě toho můžete použít +
nebo -
uložit podmínku „větší než“ nebo „menší než“.
Pojďme to pochopit na několika příkladech. Pokud chcete vypsat všechny soubory v systému o velikosti 10 KB, použijte:
find / -size 10k
Chcete-li najít soubory, které jsou větší než 1 GB, použijte:
find / -size +1G
Podobně, chcete-li najít soubory, které jsou menší než 10 MB, použijte:
find / -size -10M
Vyhledávání na základě oprávnění
Příkaz find podporuje -perm
přepněte a povolte vyhledávání na základě oprávnění. Umožňuje vyhledávat na základě číselného i symbolického režimu. Pokud oprávnění neznáte, jejich přehled naleznete zde.
Použití symbolických oprávnění
Začněme jednoduchým příkladem. Předpokládejme, že chcete vyhledat všechny soubory a adresáře v /usr
adresář s oprávněními rwxr-xr-x
. Chcete-li tak učinit, spusťte:
find /usr -perm u=rwx,g=rx,o=rx
Písmena u
, g
a o
znamená „uživatel“, „skupina“ a „vlastník“.
Můžete také použít písmeno a
zkontrolovat oprávnění, která platí pro všechny uživatele. Chcete-li například najít všechny soubory a adresáře v systému s oprávněním r-xr-xr-x
, spustit:
find /usr -perm a=rx
Často se zajímáme o shodu podmnožiny oprávnění. Můžete například chtít v systému vyhledat soubory, které mohou spustit všichni uživatelé. V tomto případě nám záleží pouze na tom, aby byl pro všechny tři třídy oprávnění nastaven prováděcí bit. Zbytek bitů však může být nastaven nebo deaktivován.
Protože všechny třídy oprávnění by měly mít nastaven bit spuštění, zapíšeme oprávnění jako a=x
. Poté přidáme /
vpředu, což znamená, že máme v úmyslu porovnat podmnožinu oprávnění. Příkaz tedy zní:
find / -type f -perm /a=x
Použití číselných oprávnění
Podívejme se na první příklad v předchozí části. To je docela jednoduché — rwxr-xr-x
je 644 v numerickém režimu, takže můžete jednoduše spustit:
find /usr -perm 644
Kontrola podmnožiny oprávnění je trochu složitější. Jak jsme již zmínili, hledání souborů, které může spustit každý, zahrnuje kontrolu, zda je nastaven spouštěcí bit. Ostatní části nás nezajímají. Pro každý bit, který bychom měli zkontrolovat, dáme 1 a pro zbytek dáme 0. Tímto procesem získáme binární číslo a převedeme ho na osmičkové, jak je znázorněno:
Dále přidáme -
před tímto číslem, což znamená, že máme v úmyslu porovnat podmnožinu oprávnění. Příkaz tedy zní:
find / -type f -perm -111
Vyhledávání na základě příznaků přístupových práv
Nyní řekněte, že vás zajímá vyhledávání na základě číselných příznaků práv. Pro tento účel můžete použít číselný nebo symbolický režim.
Řekněme například, že máte zájem najít všechny soubory ve vašem systému s nastaveným bitem setuid. To, co jsme se naučili o numerických režimech, můžeme rozšířit i na tuto situaci. V tomto případě se staráme pouze o příznak setuid, který má hodnotu 4. Nezajímá nás však žádný z bitů oprávnění, což znamená, že dostáváme 000. Tyto soubory tedy můžeme hledat pomocí:
find / -type f -perm -4000
Samozřejmě můžete také filtrovat bity oprávnění. Pokud vás zajímají soubory, které mohou spouštět všichni uživatelé, a také máte nastavený bit setuid, nahraďte 4000 4111 ve výše uvedeném příkazu. (Dříve jsme viděli, jak získáme hodnotu 111.)
Podobně můžete použít 2000 pro bit setgid a 1000 pro bit sticky. Pokud chcete otestovat kombinaci těchto bitů, sečtěte hodnoty. Například pro testování setuid a sticky bitu byste použili 5000 (=4000 + 1000).
Pokud chcete udělat totéž se symbolickými režimy, můžete použít:
find / -type f -perm /u=s
Pro bit setgid použijte /g=s
a pro lepivý bit použijte /o=t
. Chcete-li otestovat kombinaci těchto bitů, oddělte je čárkami, například /u=s,o=t
.
Omezení hloubky průchodu
Jak jsme již zmínili, příkaz find hledá položky rekurzivně. Získané výsledky však mohou být velmi rozsáhlé a možná budete chtít nastavit limit, jak hluboko může příkaz find hledat. To lze provést pomocí -maxdepth
přepínač.
Pokud spustíte následující příkaz, všimnete si, že všechny zobrazené položky nemají více než tři úrovně:
find / -maxdepth 3
V jiných situacích můžete chtít nastavit limit minimální hloubky. Příkaz find také podporuje -mindepth
přepínač pro tento účel. Pokud tedy spustíte:
find / -mindepth 3
Logické operace v příkazu find
V předchozích částech jsme viděli příznaky podporované příkazem find. Také jsme viděli, jak můžeme kombinovat různé vlajky a negovat je. V některých situacích potřebujeme výkonnější konstrukce.
Příkaz find podporuje podmínky „and“ a „or“ s -a
a -o
přepínače. Podporuje také seskupování částí výrazu se závorkami ()
. Nicméně, protože závorky jsou také speciální znaky pro shell, měli byste je dát do jednoduchých nebo dvojitých uvozovek. Navíc, když zadáte více příznaků jeden po druhém, příkaz find automaticky převezme „a“.
Podívejme se na příklad, který jsme viděli dříve – hledání adresářů uvnitř /usr
které začínají na „python“. Tam jsme použili příkaz:
find /usr -type d -name 'python*'
Můžete také napsat „a“ výslovně takto:
find /usr -type d -a -name 'python*'
Nyní se podívejme na jiný příklad. Předpokládejme, že chcete prohledávat soubory/adresáře v systému, které byly změněny za posledních 5 minut nebo dříve než za 50 dní. Pro tento příkaz použijeme operátor „or“ takto:
find / -mmin -5 -o -mtime +50
Dále předpokládejme, že na výše uvedený problém zavedeme další omezení – chcete hledat pouze soubory. Nejprve zachováme podmínky pro filtrování upravených souborů ve skupině. Poté jej „a“ s podmínkou najít soubory. Konečný příkaz je tedy:
find / '(' -mmin -5 -o -mtime +50 ')' -a -type f
Od -a
je implicitní, můžete jej také vynechat z výše uvedeného příkazu.
Provádění akcí
Zatím všechny příkazy find vypisují výsledky na terminálu. Obvykle chceme s těmito výsledky provést nějaké akce, jako je kopírování nebo mazání těchto položek. Naštěstí příkaz find také podporuje provádění „akcí“ s těmito výsledky.
Výchozí akcí je tisk všech výsledků; můžete to ověřit přidáním -print
přepínač na konci jakéhokoli příkazu find. Existuje také mnoho dalších akcí. Níže se podíváme na některé z nejužitečnějších.
Mazání souborů
Chcete-li odstranit jakékoli soubory nebo adresáře, použijte -delete
akce. Pracuje se soubory i adresáři. Pokud například chcete odstranit všechny prázdné adresáře z domovského adresáře, spusťte:
find ~ -type d -empty -delete
Provádění příkazů
Příkaz find také podporuje provádění vlastního příkazu s -exec
přepínač.
Předpokládejme, že chcete zálohovat veškerý zvuk MP3 z domovského adresáře na externí pevný disk. Předpokládejme, že externí pevný disk je dostupný na adrese /media/MyDrive
. Chcete-li zkopírovat jeden soubor, použijte:
cp <path to file> /media/MyDrive
Chcete-li zkopírovat všechny soubory, můžete použít následující příkaz.
find ~ -type f -name '*.mp3' -exec cp {} ';'
Zde je dvojice složených závorek ({}
) funguje jako zástupný symbol pro cestu k souboru. Abychom příkazu file řekli, kde příkaz končí, použijeme středník (;
). Protože je to však také speciální znak pro shell, zabalíme jej do jednoduchých uvozovek.
Kdykoli příkaz find najde soubor odpovídající podmínce, nahradí složené závorky skutečnou cestou a provede příkaz. Takže cp
příkaz se provede pro každý soubor MP3.
Podívejme se na další důležité použití — hledání řetězce v mnoha souborech. K vyhledání řetězce „ahoj“ v souboru použijeme grep takto:
grep hello <file name>
Pokud jste obeznámeni s grep
, můžete být v pokušení napsat příkaz jako tento:
find ~ -type f -exec grep hello {} ';'
Pokud však použijete tento příkaz, okamžitě pochopíte problém. Chceme seznam souborů s řetězcem „ahoj“; nicméně získáme seznam odpovídajících řádků. Naštěstí grep
má -l
přepínač, který umožňuje vytisknout cestu k souboru, pokud existuje shoda. Příkaz tedy bude:
find ~ -type f -exec grep -l hello {} ';'
Provádění příkazů:jiná varianta
Předpokládejme, že chcete vytvořit komprimovaný soubor. Chcete-li vytvořit soubor komprimovaný Gzip s názvem music.tar.gz
, spustíte:
tar -czf music.tar.gz <list of files>
Nyní předpokládejme, že chcete zkomprimovat všechny soubory MP3 ve vašem domovském adresáři do jediného komprimovaného souboru. Možná byste přišli s následujícím:
find ~ -type f -name '*.mp3' -exec tar -czf music.tar.gz {} ';'
Pokud však otevřete soubor music.tar.gz
soubor, všimnete si, že existuje pouze jeden soubor MP3. Pamatujte, že find
vykoná příkaz pokaždé, když najde nový soubor. Takže předchozí soubor byl pokaždé přepsán novým archivem; a my nechceme, aby se to stalo.
Všechny naše problémy by mohly být vyřešeny, kdyby existoval způsob, jak sdělit find
pro předání seznamu souborů tar
, poté, co najde všechny soubory. Zde je druhá varianta -exec
přichází přepínač. Místo ukončení příkazu ;
, používáme +
takhle:
find ~ -type f -name '*.mp3' -exec tar -czf music.tar.gz {} +
Provádění příkazů v adresářích
Někdy je užitečné provést příkaz v adresáři, ve kterém se nachází soubor/adresář. Příkaz find má -execdir
přepínač, který to dělá. Je podobný -exec
všemi ostatními způsoby a má dokonce +
a ;
varianty.
Zobrazení informací o souboru
Pokud chcete zobrazit informace o souborech/adresářích (jako jsou oprávnění a velikost), můžete použít -ls
přepínač. Pokud například chcete zobrazit podrobnosti o souborech v systému, které jsou větší než 1 GB, spusťte:
find / -type f -size +1G -ls
Odstranění chybových zpráv
Při pokusu o některé z příkazů hledání můžete mít nějaké chyby, jako je „Povolení odepřeno“. Tyto chybové zprávy můžete skrýt jejich přesměrováním na /dev/null
, jak je znázorněno:
find [paths] [expression] [actions] 2>/dev/null
Závěr
V tomto článku jsme viděli, jak používat příkaz find, spolu s příklady, které pokrývají většinu případů použití. Pokud si chcete přečíst více, můžete si přečíst manuálovou stránku zadáním man find
ve vašem terminálu.