Nepotřebujete roury, xargs, exec ani nic jiného:
find . -name .svn -delete
Upravit: Dělám si srandu, evidentně -delete
volání unlinkat()
pod kapotou, takže se chová jako unlink
nebo rmdir
a odmítne pracovat s adresáři obsahujícími soubory.
To, co jste napsali, odešle seznam názvů souborů (a cest) oddělených novými řádky do rm
, ale rm neví, co s tímto vstupem dělat. Očekává pouze parametry příkazového řádku.
xargs
vezme vstup, obvykle oddělený novými řádky, a umístí je na příkazový řádek, takže přidáním xargs funguje to, co jste měli:
find . -name .svn | xargs rm -fr
xargs
je natolik inteligentní, že předá pouze tolik argumentů rm
jak může přijmout. Pokud byste tedy měli milion souborů, mohlo by to spustit rm
1 000 000/65 000krát (pokud by váš shell mohl přijmout 65 002 argumentů na příkazovém řádku {65k souborů + 1 pro rm + 1 pro -fr}).
Jak lidé trefně zdůraznili, funguje také následující:
find . -name .svn -exec rm -rf {} \;
find . -depth -name .svn -exec rm -fr {} \;
find . -type d -name .svn -print0|xargs -0 rm -rf
První dva -exec
formuláře oba volají rm
pro každou odstraňovanou složku, takže pokud jste měli 1 000 000 složek, rm
bude vyvoláno 1 000 000krát. To je rozhodně méně než ideální. Novější implementace rm
umožňují ukončit příkaz +
což znamená, že rm
přijme co nejvíce argumentů:
find . -name .svn -exec rm -rf {} +
Poslední verze find/xargs používá print0, což umožňuje find generovat výstup, který používá \0
jako terminátor spíše než nový řádek. Protože systémy POSIX umožňují jakýkoli znak kromě \0
v názvu souboru je to skutečně nejbezpečnější způsob, jak zajistit, aby byly argumenty správně předány do rm
nebo právě spouštěná aplikace.
Kromě toho je zde -execdir
který spustí rm
z adresáře, ve kterém byl soubor nalezen, spíše než ze základního adresáře a -depth
tím začne hloubka jako první.
Zkuste toto:
find . -name .svn -exec rm -rf '{}' \;
Před spuštěním takového příkazu často rád nejprve spustím toto:
find . -name .svn -exec ls '{}' \;