Obcování s ďáblem 16: Co se ještě dá uvařit z příkazu find - MujMAC.cz - Apple, Mac OS X, Apple iPod

Odběr fotomagazínu

Fotografický magazín "iZIN IDIF" každý týden ve Vašem e-mailu.
Co nového ve světě fotografie!

 

Zadejte Vaši e-mailovou adresu:

Kamarád fotí rád?

Přihlas ho k odběru fotomagazínu!

 

Zadejte e-mailovou adresu kamaráda:

Soutěž

Sponzorem soutěže je:

IDIF

 

Kde se narodil známý fotograf František Drtikol?

V dnešní soutěži hrajeme o:

Seriály

Více seriálů



Software

Obcování s ďáblem 16: Co se ještě dá uvařit z příkazu find

8. listopadu 2001, 00.00 | V dnešním dílu se rozloučíme s příkazem find; nejprve si však ukážeme ještě několik fint, které se často hodí.

Finta exec (a ok)

Díky tomu, že argumentem přepínače -exec může být jakýkoli příkaz, můžeme používat příkaz find pro daleko komplexnější akce, než je pouhé vyhledávání souborů.

Připomeňme, že podmínky jsou vyhodnocovány postupně zleva doprava; jakmile některá z nich neplatí, vyhodnocování skončí, a příkaz přejde na další soubor. To se dá přeformulovat ovšem také tak, že poslední příkaz se provede tehdy a jen tehdy, když všechny před ním uvedené podmínky platí.

Dejme tomu, že chceme smazat (v rámci nějaké složky a všech jejích podřízených složek) všechny obyčejné soubory, jenž končí znakem tilda ('~') — už je asi každému čtenáři jasné, jak na to:

find ... -type f -name \*~ -exec rm {} \;

Mimochodem, právě pro takovéto případy příkaz find nabízí další velmi šikovný přepínač -ok. Ten funguje stejně jako přepínač -exec, ale navíc se před provedením příkazu zeptá, míníme-li to opravdu vážně. Pokud tedy použijeme variantu

find ... -type f -name \*~ -ok rm {} \;

budeme mít možnost se ještě pro každý soubor, jehož jméno končí tildou, rozhodnout, zda jej opravdu chceme smazat nebo ne.

Opět, vynalézavosti se meze nekladou: já např. dost často používal následující příkaz pro smazání všech generovaných souborů z projektů v OpenStepu (v dnešním Cocoa by se musel namísto make použít novy pxbuild, a hledání projektů by vypadalo malinko jinak):

find ... -type d -exec fgrep -q "" {}/PB.project 2> /dev/null \; -exec make clean \;

(Podívejte se do minulého dílu na stručné vysvětlení -q a "2>/dev/null" u příkazu fgrep.)

Finta open

Snad nejčastěji se ovšem využívá příkaz open. To je příkaz pro integraci GUI a shellu, se kterým jsme se ještě nesetkali: jeho argumentem může být libovolný soubor, a příkaz open jej otevře přesně stejným způsobem, jako kdybychom na daný soubor poklepali ve finderu myší.

Chceme-li tedy vyhledat všechny dokumenty, které se zabývají alerty (jako v minulém dílu na řádku 10), a rovnou je otevřít ve standardním HTML vieweru, stačí na to jediný příkaz

find ... -name \*.html -exec fgrep -l AlertPanel {} \; -exec open {} \;

Finta print

Přepínač -print, který vypíše právě zpracovávaný soubor, už známe z minulého dílu. Můžeme jej však použít kdekoli pro zobrazení zpracovávaného souboru; pokud bychom např. chtěli v minulém příkladu vidět, co se otevírá, mohli bychom napsat

find ... -name \*.html -exec fgrep -l AlertPanel {} \; -print -exec open {} \;

Pro zajímavost, u některých velmi komplikovaných (a proto dlouhotrvajících) příkazů find jsem občas používal následující trik pro zobrazení složky, která se právě zpracovává:

find ... \( -type d -print \) -or \( ...vlastní příkazy... \)

Finta -follow

Standardně příkaz find neprochází složky, které jsou do něj jen "nalinkované" pomocí softlinků (připomeňte si pátý díl, kdy jsme linky všech druhů rozebírali podrobně). To by byl problém např. při prohledávání vývojářské dokumentace, která obsahuje linky na dokumentaci, uloženou jinde na disku:

47 /System/Documentation/Developer> find . -name \*.html -exec fgrep -l integerForKey {} \;
48 /System/Documentation/Developer>

Dokud používáme standardní linky (a ne nestandardní aliasy, viz opět pátý díl), řešení je snadné — stačí použít speciální přepínač -follow, který zajistí, že příkaz find prohledá i takovéto složky. Firma Apple má naštěstí dostatek rozumu na to, aby do dokumentace aliasy necpala, takže to skutečně funguje:

48 /System/Documentation/Developer> find . -follow -name \*.html -exec fgrep -l integerForKey {} \;
./YellowBox/Reference/Foundation/Java/Classes/NSUserDefaults.html
./YellowBox/Reference/Foundation/ObjC_classic/Classes/NSUserDefaults.html
49 /System/Documentation/Developer>

Finta xargs

Ve většině případů, kdy skládáme dohromady více přepínačů v příkazu find, bývá "-exec grep ..." až na samém konci. V těchto případech můžeme využít trochu jiný trik, který dělá přesně to samé, ale je o poznání rychlejší: necháme find ať si hledá, a volání grepu svěříme příkazu xargs:

49 /System/Documentation/Developer> find . -follow -name \*.html | xargs fgrep -l integerForKey
./YellowBox/Reference/Foundation/Java/Classes/NSUserDefaults.html
./YellowBox/Reference/Foundation/ObjC_classic/Classes/NSUserDefaults.html
50 /System/Documentation/Developer>

Jak je vidět, získali jsme stejný výpis, jako při použití přepínače -exec v předcházejícím příkladu na řádku 48; tato varianta však byla dobře třikrát rychlejší. Příkaz xargs se dá samozřejmě použít i v řadě dalších případů, ty si ale prozatím popisovat nebudeme (samozřejmě, kdo je nedočkavý, může hned zkusit man xargs). Jen poslední finta: pokud je možné, že ve jménech prohledávaných souborů budou speciální znaky (např. mezery), je zapotřebí to oběma příkazům naznačit pomocí speciálních přepínačů:

find ...přepínače... -print0 | xargs -0 ...příkaz...

Na co se můžete těšit?

Příště si trochu rozebereme regulerní výrazy, abychom se mohli blíž podívat na řadu velmi flexibilních příkazů, jež s nimi pracují — samozřejmě již známý grep, nebo řádkový editor sed.

Obsah seriálu (více o seriálu):

Tématické zařazení:

 » Rubriky  » Informace  

 » Rubriky  » Agregator  

 » Rubriky  » Tipy a Triky  

 » Rubriky  » Začínáme s  

 » Rubriky  » Software  

Poslat článek

Nyní máte možnost poslat odkaz článku svým přátelům:

Váš e-mail:

(Není povinný)

E-mail adresáta:

Odkaz článku:

Vzkaz:

Kontrola:

Do spodního pole opište z obrázku 5 znaků:

Kód pro ověření

 

 

 

 

 

Přihlášení k mému účtu

Uživatelské jméno:

Heslo: