Имея в каталоге тысячу файлов данных (с одинаковым расширением), как удалить те из них, которые содержат определенный оператор параметра?
Например, если я захочу удалить все файлы, содержащие строку
Key = 0
Могу ли я сделать что-то вроде
grep -i "Key = 0" * | rm *
решение1
Вы можете использовать следующую команду в оболочке. Это должно сработать, если шаблон для поиска —Key = 0
grep -lrIZ "Key = 0" . | xargs -0 rm -f --
Общая команда:
grep -lrIZ "<Pattern to be searched in the file>" . | xargs -0 rm -f --
решение2
Основная проблема с конвейером, использующим grep
+, rm
заключается в том, что он rm
не считывает данные из своего стандартного входного потока, что означает, что он ничего не считывает из grep
команды в левой части конвейера.
Вместо этого rm *
в правой части канала будут игнорироваться все входные данные и выполняться rm
все видимые имена файлов в текущем каталоге.
Если не обращать внимания на проблему с rm
нечтением стандартного ввода, то у вашей grep
команды есть две основные проблемы:
- Он выводит соответствующие строки с именами файлов. Это было бы бесполезно,
rm
так как нам нужно знатьтолькоимена файлов, которые мы хотим удалить. - Он соответствует
Key = 0
какподстрока, что означает, что он также соответствуетCrypto Key = 0x01
и т. д.
find . -type f -exec grep -q -F -x 'Key = 0' {} \; -exec rm -f {} +
или, с GNU find
(и некоторыми другими),
find . -type f -exec grep -q -F -x 'Key = 0' {} \; -delete
Оба они будут искать обычные файлы в текущем каталоге или ниже, и для каждого найденного файла, он будет выполнять grep -q -F -x 'Key = 0'
. Эта grep
команда вернет статус выхода, сигнализирующий, есть ли в файле строка, котораяточно Key = 0
(и ничего больше).
Вторая find
команда удалит файл, используя его -delete
предикат, если такая строка будет найдена. Первая find
команда соберет пути файлов, содержащих эту строку, а затем запустит rm -f
их на пакетах.
Флаги, используемые с grep
:
-q
, для тихой работы. Утилита не выводит совпадающие строки, но успешно завершает работу после первого совпадения или с ненулевым статусом выхода, если файл не содержит совпадения.-F
, для фиксированного соответствия строк. Мы сопоставляем строку, а не регулярное выражение.-x
, чтобы найти только совпадения по всей строке. Это имеет тот же эффект, что и использование регулярного выражения, привязанного как к началу, так и к концу строки.
Я не использую здесь -i
with grep
, так как это также удалит файлы, содержащие строки типа KEY = 0
и kEY = 0
т. д., а вы ничего не сказали об этих вариациях регистра.
Хотите ли вы, чтобы find
команда была ограничена определенным суффиксом имени файла, например .ext
, тогда используйте -name '*.ext'
в find
команде перед выполнением grep
. Например:
find . -name '*.ext' -type f -exec grep -q -F -x 'Key = 0' {} \; -exec rm -f {} +