Я хочу удалить все файлы, которые содержат строку foo . Как я могу сделать это, используя bash в Linux?
3 ответа
Вот безопасный способ:
grep -lrIZ foo . | xargs -0 rm -f --
-lвыводит имена файлов, соответствующие шаблону поиска.-rвыполняет рекурсивный поиск шаблонаfooв заданном каталоге., Если это не сработает, попробуйте-R.-I(заглавнаяi) вызывает пропуск двоичных файлов, таких как PDF.-Zгарантирует, что имена файлов заканчиваются на ноль (т. Е. На ноль), так что имя, содержащее пробел, не интерпретируется неправильно (т. Е. Как несколько имен вместо одного).xargs -0имена файлов изgrepвrm -f, отделяя слова нулевыми (nul) байтами (помните параметр-Zизgrep).--часто забывают, но очень важно отметить конец параметров и разрешить удаление файлов, имена которых начинаются с-.
Если вы хотите увидеть, какие файлы будут удалены, просто удалите | xargs -0 rm -f -- part, и отключите опцию Z для grep .
Другой пользователь предложил что-то вроде следующего, которое вы не должны запускать, потому что это небезопасно:
files=`grep foo * | cut -d: -f1`
rm -f $files # unsafe, do not run it!
Если у меня есть файлы ImportantStuff которые я не хочу удалять, и которые obsolete ImportantStuff содержит foo , тогда я теряю ImportantStuff (а не obsolete ImportantStuff !) когда я запускаю эту команду, потому что $files разрывается на пробелы, когда она интерпретируется. Таким образом, опасно помещать список имен файлов в скалярную переменную оболочки.
$ find -type f -exec grep -q "foo" {} \; -exec echo rm -- {} \;
Это рекурсивно ищет файлы, содержащие foo . Второй -exec запускается только в том случае, если первый exec успешно завершен, т.е. если grep совпадает. Dryrun и удалите echo если вывод кажется правильным.
Или в качестве альтернативы
$ find -type f -exec grep -q "foo" {} \; -print
а также
$ find -type f -exec grep -q "foo" {} \; -delete
как предполагает Лекенштейн.
Я бы сделал то, что говорит Адриан,
Но я бы добавил границы слов для foo, чтобы случайно не удалить файлы, содержащие "food" (если только он не удаляет все, что содержит food, то, что вам нужно).
$ find -type f -exec grep -q "\<foo\>" {} \; -delete
на самом деле, я бы перенаправил вывод перед удалением, чтобы я мог просмотреть перед удалением:
$ find -type f -exec grep -q "\<foo\>" > /tmp/list_of_files_to_delete
