Вы можете использовать быструю и грязную команду rm
, чтобы выполнить то, что вы хотите, но имейте в виду, что она подвержена ошибкам, непереносима, опасна и имеет серьезные ограничения .
Как и предлагали другие, вы можете использовать команду find
. Я бы рекомендовал использовать find
вместо rm
почти во всех случаях.
Поскольку вы упоминаете, что находитесь в системе Linux, я буду использовать в своих примерах реализацию GNU , которая входит в пакет findutils , так как это значение по умолчанию в большинстве систем Linux и это то, что я обычно рекомендую изучать, поскольку он обладает гораздо более богатым и расширенным набором функций, чем многие другие реализации.
Хотя это может быть пугающе и , казалось бы, слишком сложным , стоит потратить время на освоение команды find
, потому что она дает вам некоторую точную выразительность и безопасность , которую вы не найдется с большинством других методов без существенного (плохого) переизобретения этой команды!
Найти пример
Люди часто предлагают использовать команду find
в неэффективным, подверженным ошибкам и опасным способам , поэтому ниже я обрисую безопасный и эффективный способ для достижения именно того, о чем вы просили в вашем примере.
Перед удалением файлов я рекомендую предварительно просмотреть список файлов (или хотя бы часть списка, если он очень длинный):
find path/to/files -type f -regextype posix-extended -iregex '.*\.(avi|mkv|wmv|mp4|mp5|flv|M4V|mpeg|mov|m1v|m2v|3gp|avchd)$'
Приведенная выше команда покажет вам список файлов, которые вы будете удалять. Чтобы фактически удалить файлы, вы можете просто добавить действие -delete
следующим образом:
find path/to/files -type f -regextype posix-extended -iregex '.*\.(avi|mkv|wmv|mp4|mp5|flv|M4V|mpeg|mov|m1v|m2v|3gp|avchd)$' -delete
Если вы хотите увидеть, что останется, вы можете инвертировать совпадения в предварительном просмотре, добавив !
к команде предварительного просмотра ( без * -delete
) следующим образом:
find path/to/files -type f -regextype posix-extended ! -iregex '.*\.(avi|mkv|wmv|mp4|mp5|flv|M4V|mpeg|mov|m1v|m2v|3gp|avchd)$'
Вывод этого обратного совпадения должен совпадать с выводом, который вы увидите при выводе списка файлов после выполнения удаления, если только ошибки не возникли из-за проблем с правами доступа или неписываемых файловых систем:
find path/to/files -type f
* * Объяснение тысячи сорок-девять
Здесь я подробно объясню варианты, которые я выбрал, и почему:
Я добавил -type f
к ограничить совпадения только для файлов ; без этого он будет соответствовать не-файлам, таким как каталоги, которые вы, вероятно, не хотите. Также обратите внимание, что я ставлю это в начале, а не в конце, потому что порядок предикатов может иметь значение для скорости; сначала -type f
выполняет проверку регулярных выражений только для файлов, а не для всего ... на практике это может не иметь большого значения, если у вас нет лотов каталогов или файлов. Тем не менее, стоит помнить порядок предикатов, поскольку в некоторых случаях это может оказать существенное влияние.
Я использую опцию без учета регистра -iregex
, в отличие от опции -regex
с учетом регистра, потому что я предполагал, что вы хотите использовать сопоставление без учета регистра, поэтому оно будет включать оба .wmv
и .WMV
файлов.
Возможно, вы захотите использовать расширение регулярных выражений POSIX для простоты и краткости. К сожалению, для -regextype posix-extended
пока нет короткой руки, но я все равно рекомендовал бы использовать ее, потому что вы можете избежать проблемы с добавлением большого количества обратных слешей \
, чтобы избежать более длинных, более сложных регулярных выражений, и он имеет более продвинутые (современные) функции. В реализации GNU по умолчанию используется регулярные выражения в стиле emacs , что может сбить с толку, если вы к ним не привыкли.
Опция -delete
должна иметь очевидный смысл, однако иногда люди предлагают использовать более медленную и более сложную опцию -exec rm {} \;
, но обычно это происходит потому, что они не знают о более безопасной, быстрой и простой опции -delete
( и в редких случаях вы можете встретить старые системы с древней версией find
, у которой нет этой опции). Полезно знать, что -exec
существует, но используйте -delete
, где вы можете для удаления файлов. Кроме того, не передавайте |
вывод find
в другую программу, если вы не используете и не понимаете опцию -print0
, в противном случае вы столкнетесь с огромной болью, когда столкнетесь с файлами с пробелами.
Аргумент path/to/files
, который я включил явно. Если вы пропустите его, он будет неявно использовать .
в качестве пути, однако безопаснее (особенно с -delete
) явно указать путь.
Альтернативные реализации находок
Даже если вы сказали, что работаете в системе Linux, я также упомяну о различиях, с которыми вы столкнетесь при реализации BSD , в которую входит Mac OS X ! Для других систем (таких как старые версии Solaris), удачи! Обновите до одного из более современных find
вариантов!
Основное различие в этом примере касается регулярных выражений. Варианты BSD по умолчанию используют базовые регулярные выражения POSIX. Чтобы избежать обременительного дополнительного экранирования в регулярных выражениях, необходимых для basic-PRE, вы можете воспользоваться более современными функциями расширенного PRE, указав опцию -E
с вариантом BSD для достижения того же поведения, что и у варианта GNU, использующего -regextype posix-extended
.
find -E path/to/files -iregex '.*\.(avi|mkv|wmv|mp4|mp5|flv|M4V|mpeg|mov|m1v|m2v|3gp|avchd)$' -type f
Обратите внимание, что в этом случае опция -E
стоит до path/to/files
, тогда как опция -regextype posix-extended
для GNU идет после пути.
Жаль, что GNU пока не предоставляет опцию -E
(пока!); так как я думаю, что было бы полезно иметь паритет с вариантами BSD, я отправлю патч на findutils
, чтобы добавить эту опцию, и если он будет принят, я обновлю этот ответ соответствующим образом.
rm - Не рекомендуется
Хотя я настоятельно рекомендую не использовать rm
, я приведу примеры того, как выполнить более или менее то, что конкретно задал ваш вопрос (с некоторыми оговорками).
Предполагая, что вы используете оболочку с синтаксисом Bourne (обычно это то, что вы найдете в системе Linux, которая по умолчанию используется в оболочке Bash), вы можете использовать эту команду:
for ext in avi mkv wmv mp4 mp5 flv M4V mpeg mov m1v m2v 3gp avchd; do rm -f path/to/files/*.$ext; done
Если вы используете Bash и включили расширенную глобализацию с помощью shopt -s extglob
, тогда вы можете использовать Сопоставление с шаблоном с расширением имени файла :
rm -f path/to/files/*.+(avi|mkv|wmv|mp4|mp5|flv|M4V|mpeg|mov|m1v|m2v|3gp|avchd)
Расширенный синтаксис глобализации +(pattern-list)
будет соответствовать одному или нескольким вхождениям данных шаблонов.
Однако я настоятельно рекомендую не использовать rm
, потому что:
Это подвержено ошибкам и опасно , потому что легко случайно поставить пробел между *
, что означает, что вы удалите все ; вы не можете предварительно просмотреть результат команды заранее; это Огонь и забывай , так что удачи в последствии.
Это непереносимый , потому что даже если это работает в вашей конкретной оболочке, эта же командная строка может не работать в других оболочках (включая другие варианты оболочки Bourne, если вы склонны использовать Bash -измы).
У него строгие ограничения , потому что если у вас есть файлы, вложенные в подкаталоги, или даже просто множество файлов в одном каталоге, то вы быстро достигнете ограничений по длине командной строки при использовании подстановки файлов.
Хотелось бы, чтобы команда rm
просто забыла о rm
, потому что я могу вспомнить несколько мест, где я предпочел бы использовать rm
вместо (даже древних реализаций) find
.