Вопрос: Как удалить все файлы в каталоге, кроме некоторых?


Мне нужно удалить все файлы в каталоге, но исключить некоторые из них. Например, в каталоге с файлами a b c ... z, Мне нужно удалить все, кроме u а также p, Есть простой способ сделать это?


119
2018-01-08 12:17


Источник


Ответы ниже намного лучше, но вы можете просто сделать файлы для сохранения только для чтения, удалить все и затем вернуть их обратно к своим первоначальным разрешениям (если вы не используете rm -f). Вы должны знать, какие разрешения необходимо восстановить, и вам нужно было бы знать, что во время процесса им не нужен доступ на запись. Вот почему другие ответы лучше. - Joe
Если вы также хотите удалить скрытые файлы, выполните shopt -s dotglob перед запуском rm (...),


Ответы:


То, что я делаю в этих случаях, - это ввести

rm *

Затем я нажимаю Ctrl+Икс,* в расширять  * во все видимые имена файлов.

Затем я могу просто удалить два файла, которые мне нравится убирать из списка, и, наконец, выполнить командную строку.


108
2018-01-08 12:18



Я думаю, это работает только до тех пор, пока список файлов, которые * расширяется слишком не слишком долго. : -} - Frerich Raabe
Esc, за которым следует *, также расширит «*». - slowpoison
@SantoshKumar: Это не имеет смысла для меня. Расширение всегда будет работать, оно не зависит от того, какую команду вы хотите использовать впоследствии. - Der Hochstapler
@OliverSalzburg Извините, комбинация немного запутанна. Я думаю, вы должны написать, как Ctrl + Shift + x + * - Santosh Kumar
@SantoshKumar: Но это не комбинация. - Der Hochstapler


к rm Все кроме u,p в bash просто введите:

rm !(u|p)

Для этого необходимо установить следующий параметр:

shopt -s extglob

Узнать больше: glob - Викиреальность Грега


143
2018-01-08 12:34



вы должны активировать «extglobbing»: shopt -s extglob - sparkie
Тебе нужно shopt -s extglob, @Выстрел. Кроме того, это просто файлы, а не каталоги, поэтому я удалил -rf вариантов в вашей команде. - slhck
Если вам нужно исключить один файл выбора файлов, попробуйте следующее: rm !(index).html, Это приведет к удалению всех файлов, заканчивающихся в «.html», за исключением «index.html». - mzuther


Вы можете использовать find

find . ! -name u ! -name p -maxdepth 1 -type f -delete
  • ! отрицает следующее выражение
  • -name указывает имя файла
  • -maxdepth 1 сделает процесс поиска только указанным каталогом (find по умолчанию перемещает каталоги)
  • -type f будет обрабатывать только файлы (а не, например, каталоги)
  • -delete удалит файлы

Затем вы можете настроить условия, справочная страница поиска

Обновить

  • Имейте в виду, что порядок элементов выражений значителен (см. Документацию)
  • Сначала проверьте свою команду, используя -print вместо -delete

    find . ! -name u ! -name p -maxdepth 1 -type f -print
    

67
2018-01-08 12:35



@Dennis Спасибо, я обновил ответ - Matteo
порядок предикатов здесь имеет решающее значение. Если поставить -delete сразу после . это будет катастрофой (удалит все файлы в CWD) - Michał Šrajer
Это можно записать более компактно, так как find . -maxdepth 1 -type f -name '[^up]' -delete - kojiro
@kojiro да, но только для файлов, которые являются только одной буквой. С более сложными именами регулярное выражение может быть беспорядочным. - Matteo
find мой лучший друг, особенно когда слишком много файлов для глобуса - Terence Johnson


Просто:

mv файлы, которые вы хотите в верхнем каталоге, rm каталог, а затем mv их обратно.


42
2018-01-08 12:22



Offcourse, mv их в каталог выше. Попытайтесь не mv их в подкаталог, который вы удаляете ... - Konerak
@Konerak: rm без -r не будет удалять подкаталоги. - reinierpost
Это будет перезаписывать файлы с тем же именем в каталоге назначения - Matteo
Я занимаюсь этим, потому что, хотя он может быть удобным, он также неатомный и эффективно удаляет все файлы из каталога в течение короткого периода времени; это неприемлемо, если, например, файлы будут совместно использоваться в сети. - sam hocevar


Совсем аналогично этот ответ но никаких специальных параметров не требуется, насколько мне известно, что «древняя» функциональность поддерживается любой (неопределенно) / bin / sh похожей на оболочку (например, bash, zsh, ksh и т. д.),

rm [^up]

15
2018-01-08 14:22



Это работает для имен файлов с 1 символом. Для более длинных имен лучше сказать ответ. - glenn jackman
Что было бы неправильно с rm [^up]*? Я делаю подобные вещи довольно часто. - Michael Kjörling
@ MichaelKjörling - это удалит все файлы, начинающиеся с u или p, а не только с именами u и p. Я думаю, что OP (@Ashot) означал a-z и u, p и т. Д. символически, а не буквально. - Sudipta Chatterjee
@HobbesofCalvin Что бы удалить все файлы не начиная с u или p, а не с тех, которые начинаются с них. - rjmunro
@rjmunro - спасибо, пропустил это! :) - Sudipta Chatterjee


Выполняя это, не найдя:

ls | grep -v '(u|p)' | xargs rm

(Edit: «u» и «v», как и в других местах здесь, используются как общие версии целых регулярных выражений. Очевидно, вам нужно быть осторожным, чтобы привязывать ваши регулярные выражения, чтобы избежать совпадения слишком многих вещей.)

Вам определенно захочется сценарий, если вы собираетесь делать большую часть этого, как предложили другие.


11
2018-01-09 03:54



grep не будет обрабатывать расширенное regexpt по умолчанию: либо используйте -E или egrep - Matteo
это исключает любой файл, содержащий u или p - Matteo
@Matteo Нет, не будет. Grep не grepping файлов, это grepping вывод команды ls. Вы думаете о чем-то вроде grep -L (u|p)' * | xargs rmгде -L означает имена файлов списка, не содержащие совпадения. - rjmunro
О, вы имеете в виду любой файл, имя которого содержит u или p, а не файл, содержащий u или p, Это верно. Вы можете исправить, используя egrep -v '^(u|p)$' - rjmunro
Здесь удаляются все, кроме этих совпадений! ls | grep -v 'vuze\|progs' | xargs rm -rf - Nick


GLOBIGNORE использует список разделенных двоеточиями

GLOBIGNORE=u:p
rm *

5
2018-01-08 16:32



Это не работает на моей оболочке (GNU bash 4.1.5 (1)). Обязательно сначала проверьте его с чем-то менее вредным, чем rm или в тестовом каталоге! - Michael Kjörling


В zsh:

setopt extended_glob  # probably in your .zshrc

тогда

rm ^(u|p)

или

rm *~(u|p)

Второй будет работать, даже если у вас есть ^ в $histchars для замены истории, и, конечно, вы можете поставить произвольный глобус до ~,


5
2018-01-09 22:34





Вернувшись в эпоху гибких дисков, у меня был исполняемый файл dos, называемый «Except», который временно перемещает вещи из текущего каталога и выполняет команду, чтобы вы могли сказать:

кроме * .txt del *. *

для удаления всего, кроме текстовых файлов.

Это было бы довольно тривиальной задачей для реализации в качестве сценария оболочки, и если это то, что вы, вероятно, будете делать более двух раз, похоже, было бы хорошей идеей.


3
2018-01-08 17:02



Это напомнило мне то же самое. Но временное перемещение из папки не может быть хорошей идеей в эпоху многозадачности :) - Sedat Kapanoglu


 find . -maxdepth 1 ! -name "u" ! -name "p" -type f -exec rm -rf {} \;

Это приведет к удалению всех файлов, кроме u и p, в unix


3
2018-01-08 17:58





Для тех, кто предпочитает указывать произвольные сложные шаблоны исключений (охватывающие все затронутые имена файлов) в полноэкранном emge, регулярном выражении postix-awk или posix-extended (см. Поиск man-страницы), я бы рекомендовал этот. Это исключает u а также p в текущем каталоге в этом примере. Это может быть удобно для скриптов.

find -regextype posix-awk ! -regex './(u|p)' -print0 | xargs -0 rm -rf

2
2018-01-08 18:16



Вам нужно указать каталог перед выражением (`find. -Regextype ...). - Matteo
-regextype будет работать только в версиях GNU - Matteo
no - моя версия поиска (debian squeeze) действительно не требует явного каталога перед выражением, если текущий каталог должен использоваться - sparkie
@sparke: это просто работает над реализацией GNU - Matteo
@sparkie: не определять каталог (первый параметр) для find является расширением GNU find команда. То же самое относится к -regextype вариант. Кроме того, ваша команда также удалит файлы в подкаталогах, тогда как исходный вопрос четко задается о файлах в каталоге. - Mikko Rantalainen