Я хочу удалить все файлы, которые содержат строку 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