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
findspustí příkaz find.-
./myfolderříká find, aby začínal adresářem./myfoldera jeho obsah. -
-mindepth 1neodpovídají./myfoldersamotný, 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