Видаліть усі підкаталоги, крім одного


10

Припустимо, у поточному каталозі є кілька підкаталогів, і один називається A.

Як видалити всі підкаталоги, крім A з Bash?

Відповіді:


23

Bash розширив глобус (спочатку тест, потім видаліть відлуння):

shopt -s extglob
echo rm -rf !(A)

(до того, як я забуду - ви можете відключити завершення історії стилів CSH, у Bash3 є помилка під час ігнорування! (. set + H

+1 Баш, якщо повно сюрпризів! Іноді вони приємні, як цей.
Олександр Левчук

Воу дуже приємно насправді! Працює як очікувалося. З shopt | grep extВи можете бачити, чи увімкнено плагін.
небезпека89


10

А як на рахунок:

mv A /tmp/
rm * -rf
mv /tmp/A .

Це дозволяє уникнути певної «дефіцитності» друкарських помилок в інших командах.


1
+1 за те, що робити здорову річ, а не сподіватися, що інструменти досить розумні. все-таки, однієї ночі, коли я тільки вивчав Linux, я скопіював ядро ​​в / tmp, перш ніж робити свою першу перекомпіляцію. це не вдалося, але стерло старий, тому я сказав: "не потійте, у мене є копія", лише щоб з'ясувати, що завдання півночі з кроном стирало його з кожним файлом старше тижня в / tmp! Мені довелося перекомпілювати ще раз, і цього разу зроби це правильно, або не перезавантажуй мене!
Хав'єр

найкраща відповідь розміщена :)
warren

3

Щось на зразок

find . -type d -not -name A -exec rm -ir {} \;

повинен робити.

редагувати

Це справді повинно бути

find . -type d -maxdepth 1 -not -name A -exec rm -ir {} \;

щоб запобігти findповторному повторенню нижче A.


3
Але це також видалить будь-які підкаталоги нижче A, як A / foo та A / bar, але збереже A / A.
TCampbell

Класно! Питання та відповіді мігрують із SO до SF ... але моя редакція вище була втрачена ...
agnul

Слід краще замінити maxdepth і ввести аргументи на зразок цього: find. -maxdepth 1 -тип d -not -name A -exec rm -ir {} \;
Spawnrider

1

Я зазвичай роблю це, опрацьовуючи команду ls, яка спочатку отримує це правильно. Я не на машині Unix, але щось на кшталт:

ls -lda "[^ A]"

Як тільки ви це зрозумієте, передайте команду

ls -lda "[^ A]" | xargs rm -rf

Не соромтеся редагувати вище, якщо я неправильно висловив свою помилку ...



1

Якщо ви хочете бути більш гнучкими, але вручну, ви можете зробити:

ls > /tmp/foo
edit /tmp/foo as you like
xargs -a /tmp/foo rm -r

Таким чином, ви можете зробити загальний обмін.


1

Ось один із способів. Будьте обережні з подібними речами, хоча вони настільки потужні, що їх можна використовувати лише для добра чи зла ...

знайти * -тип d | grep -v "^ A" | xargs rm -rf

1

Не використовуйте пошук, як показали деякі люди із -exec та rm, не передаючи -print0 для пошуку та -0 до xargs. Він буде плутати імена файлів з пробілами або новими рядками:

$ mkdir 'foo foo'
$ mkdir foo$'\n'foo 
$ find . -type d -exec rm -ir {} \;
rm: cannot remove directory `.'
rm: remove directory `./foo\nfoo'? y
find: `./foo\nfoo': No such file or directory
rm: remove directory `./foo foo'? y
find: `./foo foo': No such file or directory

Замість цього використовуйте find -print0 з xargs -0, '-exec командою {} +' або -delete, якщо ваша знахідка підтримує це.



1

На додаток до попереднього прикладу:

find -maxdepth 1 -type d -not -name A -not -name "." -exec rm -ir {} \;

Ви також можете зробити:

find some/subdir -mindepth 1 -maxdepth 1 -type d -not -name A -exec rm -ir {} \;

щоб уникнути необхідності cd some/subdirспочатку.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.