Ответы:
Использование расширенного шаблона сглаживания в bash:
rm ./!(*999*)
Это необходимо shopt -s extglobвключить (и для безопасности также shopt -s failglob, чтобы ни один файл с необычным именем !(*999*)не был удален по ошибке, если все имена файлов содержат 999). Шаблон !(*999*)будет соответствовать любому имени в текущем каталоге, кроме тех имен, которые совпадают *999*. Чтобы также удалить скрытые файлы (файлы, имя которых начинается с точки ), также включите эту dotglobопцию.
Чтобы заботиться только о обычных файлах или символических ссылках на обычные файлы (не каталоги и т. Д.):
for name in ./!(*999*); do [ -f "$name" ] && rm "$name"; done
zshЭквивалентно оболочки к петле выше будет
rm ./(^(*999*))(.)
Ваша первая команда не будет работать, так как grepбудет искать внутри файлов. Он удалит все файлы без строк 999(если вы добавили --nullопцию, чтобы она работала с xargs -0).
Ваша вторая команда не будет работать, так как grepв macOS не поддерживает --null-data(однако она имеет --nullопцию, но только для генерации вывода имени файла). Также обратите внимание , что он будет искать в 999любом месте файла в пути (включая компоненты каталога), а не только имя файла.
failglobопцию, иначе это может привести к удалению файла с именем, !(*999*)если нет другого файла, имя которого не содержит 999.
Просто инвертируйте имя условия в find:
find . -type f \! -name "*999*"
Добавить -deleteили -exec rm {} +фактически удалить соответствующие файлы.
!безопасно в bash.
grep -lзаставляет его перечислять файлы, в которых совпадение было найдено (или не найдено-v) в содержимом , а не имя файла.grepвсегда сопоставляется с содержимым указанных вами файлов, а не с их именами.