Вопрос или проблема
Я пытаюсь очистить некоторые файлы на машине с 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)'
--нет вывода--
Моя версия find
– find (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
Объяснение деталей команды
-
-regextype posix-extended
: Указывает, что мы используем расширенный POSIX-синтаксис, который поддерживает более сложные выражения без нужды в экранировании специальных символов. -
'.*/.*\.(debsess|slmcrec|div|debmeta)$'
:.*
в начале соответствует любому пути к файлу.\.
обозначает, что нам нужен буквальный символ точки.(debsess|slmcrec|div|debmeta)
— группировка, которая проверяет, соответствует ли расширение одному из указанных значений.$
в конце выражения указывает на конец строки, гарантируя, что ничего не следует за именем файла.
-
-delete
: Удаляет найденные файлы, соответствующие регулярному выражению.
Итог
После внесения этих изменений ваша команда должна работать корректно и удалять файлы с указанными расширениями из заданных директорий. Всегда проверяйте команды find
с флагом -print
или -ls
, прежде чем использовать -delete
, чтобы убедиться, что они возвращают именно те файлы, которые вы собираетесь удалить.
Используя указанные методы, вы повысите эффективность своей работы с файлами в Linux и избежите нежелательных последствий.