удалять файлы, если имя НЕ содержит слов

Я использую Linux и намерен удалить некоторые файлы с помощью оболочки.

У меня в папке есть несколько файлов, некоторые имена файлов содержат слово "хорошо", другие нет. Например:

ssgood.wmv
ssbad.wmv
goodboy.wmv
cuteboy.wmv

Я хочу удалить файлы, которые НЕ содержат «хорошо» в имени, поэтому оставшиеся файлы:

ssgood.wmv
goodboy.wmv

Как это сделать, используя rm в оболочке? я пытаюсь использовать

rm -f *[!good].*

но это не работает.

Большое спасибо!


person DocWiki    schedule 03.07.2011    source источник
comment
Вы имеете в виду, что имена файлов содержат «хорошо»? В примере, похоже, указаны имена файлов, но вы говорите, что файлы содержат слово...   -  person sarnold    schedule 03.07.2011
comment
Имена файлов содержат добро. Я не являюсь носителем английского языка. Спасибо 4 хедз-ап.   -  person DocWiki    schedule 03.07.2011


Ответы (3)


Эта команда должна делать то, что вам нужно:

ls -1 | grep -v 'good' | xargs rm -f

Вероятно, она будет работать быстрее, чем другие команды, поскольку не требует использования регулярных выражений (которые медленны и не нужны для такой простой операции).

person EdoDodo    schedule 03.07.2011
comment
+1. На самом деле, grep использует регулярные выражения и невероятно быстро. - person Alan Moore; 03.07.2011
comment
Как есть, это не сработает, потому что команда ls перечисляет несколько имен файлов в строке. Вам нужно добавить параметр "-1" один файл в строке следующим образом: ls -1 | grep ... - person ridgerunner; 03.07.2011
comment
Хм... В моей системе ls всегда перечисляет один файл в строке, так что все работало отлично. Странно, наверное, где-то это опция по умолчанию. Во всяком случае, я добавил опцию -1, чтобы она всегда работала. - person EdoDodo; 03.07.2011
comment
@EdoDodo: у вас, вероятно, есть команда alias ls='ls -1' в одном из ваших файлов запуска. - person ridgerunner; 03.07.2011
comment
Действительно полезно! Ты гений! - person Christian Vielma; 21.11.2013
comment
Это ужасный метод! Не анализировать вывод ls. - person gniourf_gniourf; 23.04.2014
comment
У меня не работает, не знаю, почему он пытается удалить (стандартный ввод) - person Rodrigo Farias Rezino; 19.11.2015
comment
как бы вы сделали это рекурсивно? - person Ciprian Tomoiagă; 02.06.2017

С помощью bash вы можете получить "отрицательное" соответствие с помощью параметра оболочки extglob:

shopt -s extglob
rm !(*good*)
person glenn jackman    schedule 03.07.2011

Вы можете использовать find с оператором -not:

find . -not -iname "*good*" -a -not -name "." -exec rm {} \;

Я использовал -exec для вызова rm там, но интересно, есть ли у find встроенное действие удаления есть, см. ниже.

Но с этим очень осторожно. Обратите внимание, что в приведенном выше примере мне пришлось добавить пункт -a -not -name ".", потому что в противном случае он соответствовал бы ., текущему каталогу. Поэтому я бы тщательно протестировал -print, прежде чем вставлять бит -exec rm {} \;!

Обновление: Да, я никогда не использовал его, но действие -delete действительно есть. Так:

find . -not -iname "*good*" -a -not -name "." -delete

Опять же, будьте осторожны и перепроверьте, не соответствуете ли вы больше, чем хотите.

person T.J. Crowder    schedule 03.07.2011
comment
Особенно хорошее предложение использовать -print в первую очередь. :) - person sarnold; 03.07.2011