Tím smažete všechny složky v ./myfolder
kromě toho ./myfolder/test2
a veškerý jeho obsah bude zachován:
find ./myfolder -mindepth 1 ! -regex '^./myfolder/test2\(/.*\)?' -delete
Jak to funguje
find
spustí příkaz find.-
./myfolder
říká find, aby začínal adresářem./myfolder
a jeho obsah. -
-mindepth 1
neodpovídají./myfolder
samotný, pouze soubory a adresáře pod ním. -
! -regex '^./myfolder/test2\(/.*\)?'
říká find, že má vyloučit (!
) jakýkoli soubor nebo adresář odpovídající regulárnímu výrazu^./myfolder/test2\(/.*\)?
.^
odpovídá začátku názvu cesty. Výraz(/.*\)?
odpovídá buď (a) lomítku následovanému čímkoli, nebo (b) vůbec nic. -
-delete
říká find, aby smazal odpovídající (tj. nevyloučené) soubory.
Příklad
Zvažte strukturu adresářů, která vypadá takto;
$ find ./myfolder
./myfolder
./myfolder/test1
./myfolder/test1/dir1
./myfolder/test1/dir1/test2
./myfolder/test1/dir1/test2/file4
./myfolder/test1/file1
./myfolder/test3
./myfolder/test3/file3
./myfolder/test2
./myfolder/test2/file2
./myfolder/test2/dir2
Můžeme spustit příkaz find (bez -delete
), abyste viděli, co odpovídá:
$ find ./myfolder -mindepth 1 ! -regex '^./myfolder/test2\(/.*\)?'
./myfolder/test1
./myfolder/test1/dir1
./myfolder/test1/dir1/test2
./myfolder/test1/dir1/test2/file4
./myfolder/test1/file1
./myfolder/test3
./myfolder/test3/file3
Můžeme ověřit, že to fungovalo, když se podíváme na soubory, které zůstaly:
$ find ./myfolder
./myfolder
./myfolder/test2
./myfolder/test2/file2
./myfolder/test2/dir2
Použití bash:
shopt -s extglob
rm -r myfolder/!(test2)/
Příklad:
$ tree myfolder/
myfolder/
├── test1
│ └── file1
├── test2
│ └── file2
└── test3
└── file3
$ echo rm -r myfolder/!(test2)
rm -r myfolder/test1 myfolder/test3
$ rm -r myfolder/!(test2)
$ tree myfolder/
myfolder/
└── test2
└── file2
1 directory, 1 file
tl;dr
find ./myfolder -mindepth 1 -maxdepth 1 -type d -not -name test2 \
-exec echo rm -rf '{}' \;
Pokud jste se seznamem souborů spokojeni, odeberte echo.
Pomocí -mindepth 1
zajistí, že nahoře adresář není vybrán.
$ find ./myfolder -mindepth 1 -type d
./myfolder/test2
./myfolder/test2/one
./myfolder/test2/two
./myfolder/test
./myfolder/test/a1
./myfolder/test/a1/a2
./myfolder/test/a1/a2/a3
Ale -not -name test2
nebude vyhnout se podadresářům uvnitř test2
:
$ find ./myfolder -mindepth 1 -type d -not -name 'test2'
./myfolder/test2/one
./myfolder/test2/two
./myfolder/test
./myfolder/test/a1
./myfolder/test/a1/a2
./myfolder/test/a1/a2/a3
K tomu potřebujete něco jako prune:
$ find ./myfolder -mindepth 1 -name test2 -prune -o -type d -print
./myfolder/test
./myfolder/test/a1
./myfolder/test/a1/a2
./myfolder/test/a1/a2/a3
Ale nepoužívejte delete
, jak to znamená depth
a to začne mazat z nejdelší cesty:
$ find ./myfolder -depth -mindepth 1 -name test2 -prune -o -type d -print
./myfolder/test/a1/a2/a3
./myfolder/test/a1/a2
./myfolder/test/a1
./myfolder/test
Buď použijte rm -rf
(odeberte echo
pokud chcete skutečně vymazat):
$ find ./myfolder -mindepth 1 -name test2 -prune -o -type d -exec echo rm -rf '{}' \;
rm -rf ./myfolder/test
rm -rf ./myfolder/test/a1
rm -rf ./myfolder/test/a1/a2
rm -rf ./myfolder/test/a1/a2/a3
Nebo také použijte maxdepth
pokud vše, co potřebujete, je smazat adresáře (a vše uvnitř) (odstraňte echo
skutečně vymazat):
$ find ./myfolder -mindepth 1 -maxdepth 1 -type d -not -name test2 -exec echo rm -rf '{}' \;
rm -rf ./myfolder/test
A -delete
stále selže, pokud adresář není prázdný:
$ find ./myfolder -mindepth 1 -maxdepth 1 -type d -not -name test2 -delete
find: cannot delete ‘./myfolder/test’: Directory not empty