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

Вопрос или проблема

Имея тысячу файлов данных (одинаковое расширение) в каталоге, как удалить те из них, которые содержат определенное параметрическое заявление?

Например, если бы я хотел удалить все файлы, содержащие строку

Key = 0

могу ли я сделать что-то такое

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

Главная проблема с использованием конвейера grep+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 {} +

или, с помощью 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 с 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 {} +

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

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

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

grep -lrIZ "<Шаблон для поиска в файле>" . | xargs -0 rm -f --

Следующий сценарий Bash перемещает все файлы, содержимое которых соответствует любым заданным шаблонам, в отдельный каталог /tmp/matching. Рассматриваются все обычные файлы в текущем каталоге.

#!/bin/bash

shopt -s nullglob dotglob

savedir=/tmp/matching

patterns=(
    -e 'pattern 1'
    -e 'pattern 2'
    -e 'pattern 3'
)

mkdir -p "$savedir" || exit

for name in *; do
    if [ ! -f "$name" ]; then
        continue
    fi

    if grep -q "${patterns[@]}" -- "$name"
    then
        mv -v -- "$name" "$savedir"
    fi
done

После выполнения сценария каталог /tmp/matching может быть инспектирован и, возможно, удален.

Используя patterns=( "$@" ), шаблоны, каждый с предшествующим -e, могут быть переданы в командной строке сценария:

$ ./thescript -e '^Key = 0$' -e '^Key: 0$'

“Тысячи файлов” вызывает мою рефлексию find/xargs.

find . -type f -name '*.ext' -print0 | \
  xargs -0 -r grep -l --null "Key = 0" | \
    xargs -0 -r rm -f

Он обрабатывает файлы с нестандартными именами, миллионы файлов, …

.

Ответ или решение

Управление файлами и очистка директории от ненужных файлов — распространённая задача в IT-сфере, особенно когда речь идёт о большом количестве данных. Потребность в удалении файлов на основании их содержимого встречается часто, будь то для освобождения места на диске или для устранения устаревшей информации. В данном контексте задача заключается в удалении файлов, содержащих определённую строку "Key = 0". В ответе мы подробно рассмотрим, как подойти к решению этой задачи, используя инструменты командной строки UNIX/Linux.

Теория

Работа с файлами на уровне командной строки требует понимания того, как интерпретатор и утилиты взаимодействуют с файлами. Основой для доступа к файлам и их содержимому служат такие инструменты, как find, grep и xargs. Рассмотрим их:

  1. find — мощная утилита для поиска файлов и директорий на основе заданных условий. Она позволяет не только искать файлы, но и выполнять команды для найденных объектов.

  2. grep — инструмент для поиска строк в файлах, подходит для фильтрации содержимого и поиска нужных шаблонов. Используется с различными опциями для точного соответствия, включая полное совпадение строки и чувствительность к регистру.

  3. xargs — утилита, преобразующая стандартный поток ввода в аргументы командной строки для других команд. Это позволяет обрабатывать данные, полученные через pipe, например, передавать их в rm для удаления.

Пример

Представим, что у нас есть директория, содержащая тысячи файлов с расширением .ext, среди которых необходимо удалить все, которые включают строку "Key = 0". Применим комбинацию команд для достижения этого.

Команда с использованием find и grep

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

Описание и логика команды:

  • find . -type f -name '*.ext' ищет все файлы с расширением .ext.
  • -exec grep -q -F -x 'Key = 0' {} выполняет команду grep для каждого найденного файла, проверяя наличие строки "Key = 0".
    • -q — тихий режим, прекращает поиск после первого найденного совпадения.
    • -F — поиск фиксированной строки, а не регулярного выражения.
    • -x — поиск полного совпадения строки.
  • Если grep находит совпадение, -exec rm -f {} выполняет удаление файла.

Команда с использованием grep и xargs

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

Описание и логика команды:

  • grep -lrIZ "Key = 0" . рекурсивно ищет файлы, содержащие строку, начиная с текущей директории.
    • -l — выводит только имена файлов.
    • -r — рекурсивный поиск.
    • -I — игнорирует бинарные файлы.
    • -Z — добавляет нулевой символ в конце каждого имени файла (удобно для обработки xargs).
  • xargs -0 rm -f -- получает имена файлов от grep и передаёт их rm для удаления.
    • -0 — позволяет xargs обрабатывать нулевые символы как разделители.

Применение

Используя приведённые примеры, вы сможете эффективно управлять файлами на вашем сервере или рабочей станции, автоматизируя удаление ненужных или устаревших данных. Эти команды могут быть интегрированы в более сложные скрипты для регулярной очистки директорий или при подготовке данных для анализа или архивации.

Применение таких техник важно для администраторов систем, позволяет поддерживать чистоту и эффективность файловых систем, оптимизируя использование пространства на диске и управляя большим объёмом данных без излишнего вмешательства пользователя.

Рекомендации

  • Всегда создавайте резервные копии важной информации перед выполнением массовых операций с файлами.
  • Тестируйте команды на ограниченном наборе данных для предотвращения случайного удаления критичных данных.
  • Используйте grep и find с осторожностью, если ваши данные чувствительны к регистру или содержат специфичные символы.

Таким образом, вы сможете эффективно и безопасно управлять данными, минимизируя риск человеческой ошибки и повышая производительность вашей системы.

Оцените материал
Добавить комментарий

Капча загружается...