найти -regex для нескольких расширений

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

Я пытаюсь очистить некоторые файлы на машине с Debian 11.

Эти файлы находятся в подкаталоге в:

  • /tmp/.debrief, или
  • /opt/site/var/debrief

Я могу идентифицировать их по расширению в имени файла:

  • .debsess,
  • .slmcrec,
  • .div, или
  • .debmeta

Я думал, что использование флага -regex утилиты GNU find и флага -delete будет идеальным:

find /tmp/.debrief /opt/site/var/debrief \
    -regex '.*\.(?:div|debmeta|slmcrec|debsess)' \
    -delete

Но, похоже, он не находит ни один из файлов, которые я вижу. Тогда я понял, что find не реализует pcre напрямую:

$ find -regextype help
действительные типы: ‘findutils-default’, ‘ed’, ‘emacs’, ‘gnu-awk’, ‘grep’, ‘posix-awk’, 
‘awk’, ‘posix-basic’, ‘posix-egrep’, ‘egrep’, ‘posix-extended’, 
‘posix-minimal-basic’, ‘sed’.

Я почти уверен, что GNU grep не реализует группы захвата без -E, но egrep делает это:

$ ls /tmp/.debrief | egrep '.*\.(div|debmeta|slmcrec|debsess)'
1R_camera.div
1R.debmeta
4Ahi_camera.div
4Ahi.debmeta
...

Но find все равно, похоже, не находит эти файлы:

$ find /tmp/.debrief /opt/site/var/debrief \
    -regextype egrep \
    -regex '.*\.(div|debmeta|slmcrec|debsess)'
--нет вывода--

Моя версия findfind (GNU findutils) 4.8.0.

Что я упустил?


Редактирование: Вывод egrep по запросу в комментариях:

$ ls /tmp/.debrief | egrep '.*\.(div\debmeta|slmcrec|debsess)' | LC_ALL=C sed -n l
1R.slmcrec$
28.11.debsess$
4Ahi.slmcrec$
Cc7.slmcrec$
dc.slmcrec$
h0M.slmcrec$
hWdxlm.slmcrec$
i79W.slmcrec$
ILWm7b.slmcrec$
izebDM.slmcrec$
K7yUk.slmcrec$
kIziXi.slmcrec$
L4XWy.slmcrec$
M.slmcrec$
NR.slmcrec$
Nz7.slmcrec$
o7qXQ.slmcrec$
oD.slmcrec$
pAupd0.slmcrec$
pwxh.slmcrec$
uCptRo.slmcrec$
vWsP9.slmcrec$
YMYtEi.slmcrec$
zV6.slmcrec$

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

Когда вы работаете над очисткой файлов в Debian 11 с использованием утилиты find, важно учитывать, как работает флаг -regex, поскольку его поведение может не соответствовать ожиданиям. Давайте разберем вашу ситуацию и предложим правильное решение.

Анализ проблемы с find -regex

Ваше выражение:

find /tmp/.debrief /opt/site/var/debrief \
    -regex '.*\.(?:div|debmeta|slmcrec|debsess)' \
    -delete

не дает ожидаемого результата, потому что find использует регулярные выражения, которые по умолчанию не поддерживают конструкции, такие как (?:...) для группировки без захвата. Также стоит отметить, что регулярное выражение для find использует полное соответствие пути файла. Это значит, что в регулярном выражении должны присутствовать начальные и конечные элементы пути.

Использование правильного синтаксиса

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

find /tmp/.debrief /opt/site/var/debrief \
    -regextype posix-extended \
    -regex '.*/.*\.(debsess|slmcrec|div|debmeta)$' \
    -delete

Объяснение деталей команды

  1. -regextype posix-extended: Указывает, что мы используем расширенный POSIX-синтаксис, который поддерживает более сложные выражения без нужды в экранировании специальных символов.

  2. '.*/.*\.(debsess|slmcrec|div|debmeta)$':

    • .* в начале соответствует любому пути к файлу.
    • \. обозначает, что нам нужен буквальный символ точки.
    • (debsess|slmcrec|div|debmeta) — группировка, которая проверяет, соответствует ли расширение одному из указанных значений.
    • $ в конце выражения указывает на конец строки, гарантируя, что ничего не следует за именем файла.
  3. -delete: Удаляет найденные файлы, соответствующие регулярному выражению.

Итог

После внесения этих изменений ваша команда должна работать корректно и удалять файлы с указанными расширениями из заданных директорий. Всегда проверяйте команды find с флагом -print или -ls, прежде чем использовать -delete, чтобы убедиться, что они возвращают именно те файлы, которые вы собираетесь удалить.

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

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

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