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

Я взял неправильную версию документации. Я установил bounce_message_file, чтобы файл содержал шаблон в формате из этого :документация exim 4.84 и ее работа в полном порядке.

2
19.06.2021, 07:14
1 ответ

С помощью zsh, чтобы уточнить формат имен файлов, которые вы хотите:

print -rC1 -- **/Name(-<->x<->|)(@<->x|).jpg(DN)
  • print -rC1:printrавон1Cколонна
  • **/:рекурсивная подстановка
  • (a|b):чередование, поэтому (x|)похоже на ERE(x)?
  • <x-y>:последовательность десятичных цифр, представляющая целые числа от x до y, <->последовательность цифр, представляющая любое число.
  • D:dotglob:также смотрите в скрытых каталогах, как это делает find.
  • N:nullglob:Не жалуйтесь, если совпадений нет, и вместо этого расширяйтесь до нуля.

Эквивалент GNU find(без сортировки файлов и с префиксом ./к каждому пути):

LC_ALL=C find. -regextype posix-extended -regex \
  '.*/Name(-[0-9]+x[0-9]+)?(@[0-9]+x)?\.jpg'

(с BSD find, используйте find -E.вместоfind. -regextype posix-extended)

Со стандартным find, возможно:

find. -name '.*/Name[-@.]*'

Было бы достаточно, если бы все, что вам нужно, это исключить NameLonger.

Простые подстановочные шаблоны не имеют эквивалента для операторов +, ?или |. Можно было бы сделать что-то эквивалентное с числом -nameи ! -name, объединенных И и объединенных по ИЛИ вместе (, например принять Name-*x*.jpg, но отклонить Name-*[!0-9]*x*[!0-9]*.jpg, Name-x*, Name-*x.jpgи т. д. ), но это было бы чрезвычайно громоздко, так как вам потребуются сотни из них для обработки всех случаев.

Можно указать, что реализация GNU libc функции fnmatch()(, используемая find -name), поддерживает некоторые расширенные операторы glob ksh88(FNM_EXTMATCHфлаг ), которые обеспечивают эквивалентность регулярных выражений (и +(...), ?(...)... также поддерживается zsh -o kshglobили bash -O extglob), но, насколько мне известно, даже реализации GNU findнельзя сказать, чтобы они использовали их.

POSIX, вы можете прибегнуть к awkдля уточнения соответствия:

LC_ALL=C find. -name 'Name*' -exec awk '
  BEGIN {
    for (i = 1; i < ARGC; i++)
      if (ARGV[i] ~ "/Name(-[0-9]+x[0-9]+)?(@[0-9]+x)?\\.jpg$")
        print ARGV[i]
  }' {} +

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

4
28.07.2021, 11:23

Теги

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