Відповіді:
Використання розширеного шаблону глобалізації в 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завжди відповідає вмісту файлів, які ви вказуєте, ніколи їх імена.