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