Я столкнулся с той же проблемой. Для меня работает добавление опцииvers=2.0
Да, здесь вам нужно сгенерировать 3 аргумента для find
для каждого элемента вашего массива. Также find
's -name
принимает шаблон, поэтому, чтобы он соответствовал точным именам файлов, вам нужно экранировать операторы подстановочных знаков find
(*
, ?
, [
и \
):
set -o extendedglob # for (#m)
exclusions=()
for name ($drivers) exclusions+=(! -name ${name//(#m)[?*[\\]/\\$MATCH})
find ${refind_efi_dir}drivers_x64/ $exclusions -type f -exec rm -f {} +
"${array[@]/pattern/replacement}"
расширяется до такого количества элементов, которое есть в массиве, после подстановки, выполненной для каждого из них.
Здесь, учитывая, что -name
принимает шаблон имени файла , он не должен содержать /
, поэтому вы можете заменить каждый элемент на !/-name/element
, а затем разделить на/
:
set -o extendedglob # for (#m)
find ${refind_efi_dir}drivers_x64/ \
${(@s[/])${drivers//(#m)[?*[\\]/\\$MATCH}/#/!\/-name\/} \
-type f -exec rm -f {} +
Или используйте $'\0'
вместо /
, так как его нельзя передать в качестве аргумента внешней команде:
set -o extendedglob # for (#m)
find ${refind_efi_dir}drivers_x64/ \
${(@0)${drivers//(#m)[?*[\\]/\\$MATCH}/#/!$'\0'-name$'\0'} \
-type f -exec rm -f {} +
Но разборчивости это не сильно способствует...
Здесь вы также можете использовать zsh
glob для всего:
(cd -P -- $refind_efi_dir && rm -f -- **/^(${(~j[|])drivers})(D.))
Если флаг расширения параметра j[|]
объединяет элементы массива $drivers
с |
и ~
, это приводит к тому, что |
рассматривается как оператор глобуса. Этот шаблон инвертируется с помощью ^
(, для которого вам нужна опция extendedglob
). D
для включения скрытых файлов, .
для ограничения обычными файлами, такими как ваш -type f
.
"${drivers[@]/#/! -name }"
помещает ! -name
в то же слово оболочки, что и каждый элемент массива. "${=drivers[@]/#/! -name }"
разделит результаты, так что !
и -name
окажутся отдельными словами оболочки, но элементы массива также будут разделены пробелами.
Одним из решений является злоупотребление квалификаторами e
иP
glob:
find … /(e\''reply=($drivers)'\'P\''!'\'P\''-name'\') …
/(…)
расширяет шаблон glob /
, который всегда соответствует ровно одному (корневому каталогу ), и применяет к нему квалификаторы glob. Квалификатор glob e
заменяет каждое совпадение новым значением переменной-массива reply
, которую мы устанавливаем в список слов, к которым мы хотим применить последующие квалификаторы glob. Затем квалификатор glob P
,используется дважды, вставляет указанный текст как отдельные слова перед каждым совпадением.
В этом конкретном случае , как показал Стефан Шазела , вы можете просто делать все с помощью zsh globs, не используя find.