Удалить файлы с определенным содержимым

strace показывает мне, что ls -iвызывает lstat()для каждого имени файла

Это объясняет дополнительную работу.

Учитывая, что readdir ()уже вернул номер инода, это кажется менее -оптимальным

Хотя это похоже на ошибку, такое поведение связано с согласованностью точек монтирования. (см. комментарий Томаса)

-1
12.08.2020, 12:58
2 ответа

В оболочке можно использовать следующую команду. Это должно сработать, если искомый шаблонKey = 0

grep -lrIZ "Key = 0". | xargs -0 rm -f --

Общая команда:

grep -lrIZ "<Pattern to be searched in the file>". | xargs -0 rm -f --
0
18.03.2021, 23:13

Основная проблема с предложенной вами командой,

grep -i "Key = 0" * | rm *

заключается в том, что rmне читает из своего стандартного входного потока, что означает, что он ничего не читает из команды grepв левой части конвейера.

Вместо этого rm *в правой части канала будет игнорировать все входные данные и просто выполнять rmдля каждого видимого имени файла в текущем каталоге.

Игнорируя проблему с тем, что rmне читает стандартный ввод, ваша команда grepимеет две основные проблемы:

  1. Выводит совпадающие строки с именами файлов. Это было бы бесполезно для rm, так как нам нужно знать только имена файлов, которые мы хотим удалить.
  2. Он соответствует Key = 0как подстрока , что означает, что он также соответствует таким строкам, как Crypto Key = 0x01и т. д.

find. -type f -exec grep -q -F -x 'Key = 0' {} \; -exec rm -f {} +

или, с GNUfind(и некоторыми другими ),

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с 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 {} +
1
21.03.2021, 20:24

Теги

Похожие вопросы