2016-11-29 5 views
1

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

Мой сценарий оболочки:

files=$(find $path -name $regex) 

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

20161128-20:34:33:432813246 
YYYYMMDD-HH:MM:SS:NS 

Я не могу найти правильное регулярное выражение.

Я могу получить путь к файлам внутри папки, используя regex '*data.txt', так как я знаю имя файла внутри него.

Но это дает мне полный путь к файлу, что-то вроде

/path/20161128-20:34:33:432813246/data.txt 

То, что я хочу, это просто:

/path/20161128-20:34:33:432813246 

Пожалуйста, помогите мне в определении правильного регулярного выражения для моего требования

ПРИМЕЧАНИЕ:

Я знаю, как обрабатывать данные после

files=$(find $path -name $regex) 

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

+3

это не регулярное выражение, это подстановочный знак! –

+0

Вы имеете в виду, что я требую, является подстановочным знаком, а не регулярным выражением? – ADPK

+0

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

ответ

3
  • Per POSIX, find «s -name-path праймериз (тесты) использовать patterns (так называемые подстановочные выражения, globs) t o соответствовать именам файлов и именам путей (в то время как шаблоны и регулярные выражения дистанционно связаны, их синтаксис и возможности существенно различаются; короче: шаблоны синтаксически проще, но гораздо менее мощные).

    • -name и соответствует шаблону против базового (просто имя файла) части входного пути только
    • -path соответствует шаблону против всего пути (полного пути)
  • И GNU, и BSD/macOS find реализация нестандартные расширения:

    • -iname и -ipath, которые работают, как их стандартные-совместимые аналоги (на основе моделей), за исключением того, что они соответствуют регистронезависимо.
    • -regex и -iregex тесты на соответствие имен путей с помощью регулярное выражение (регулярное выражение).
      • Оговорки: Оба реализации предлагают по крайней мере, 2 регулярных выражения диалектов на выбор (-E активирует поддержку расширенного регулярных выражений в BSD find и GNU find позволяет выбрать из нескольких диалектов с -regextype, но никаких два диалекта не точно же через две реализации - см дно для окровавленных деталей

.

С вашими именами папок после схемы именования фиксированной ширины, модель будет работать:

pattern='[0-9][0-9][0-9][0-9][0-9][0-9][0-9]-[0-9][0-9]:[0-9][0-9]:[0-9][0-9]:[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]' 

Конечно, вы можете взять ярлык, если вы не ожидаете ложных срабатываний:

pattern='[0-9]*-[0-9]?:[0-9]?:[0-9]?:[0-9]*' 

Обратите внимание, как * и ?, в отличие от регулярного выражения, не являются дублирование символы (кванторы), которые относятся к предыдущему выражению, но сами по себе представляют любую последовательность символов (*) или любой символ (?).

Если мы соберем все вместе:

files=$(find "$path" -type d -name "$pattern") 
  • Это важно переменных ссылок в двойных кавычках, чтобы защитить свои ценности от нежелательных расширений оболочки, в частности, для сохранения каких-либо пробелов в пути и для предотвращения преждевременного гвоздя оболочкой значения $pattern.

  • Отметьте, что я добавил -type d, чтобы ограничить соответствие каталогов (папок), что улучшает производительность.


Дополнительно справочная информация:

Ниже особенность матрицарегулярного выражения в ГНУ find v4.6.0/BSD find, как найти на MacOS 10.12.1:

  • GNU find функции указаны типом s поддерживается опцией -regextype, а emacs является значением по умолчанию.

    • Обратите внимание, что несколько posix-* -named регулярных выражений типы misnomers в том, что они поддерживают функции за, что POSIX мандатов.
  • BSD find функция перечислена basic (используя не регулярки варианта, который подразумевает платформы со вкусом BREs) и extended (с помощью опции -E, которая подразумевает платформы приправленного EREs).

Для использования кросс-платформенной, придерживающийся POSIX EREs (extended regular expressions) при использовании -regextype posix-extended с GNUfind и используя -E с BSDfind безопасна, но учтите, что не все функции, вы можете ожидать, будет поддерживаться, в частности \b , \</\> и ярлыки класса символов, такие как \d.

=================== GNU find =================== 
== REGEX FEATURE: \{\} 
TYPE: awk:          - 
TYPE: egrep:          - 
TYPE: ed:           ✓ 
TYPE: emacs:          - 
TYPE: gnu-awk:         - 
TYPE: grep:          ✓ 
TYPE: posix-awk:         - 
TYPE: posix-basic:        ✓ 
TYPE: posix-egrep:        - 
TYPE: posix-extended:        - 
TYPE: posix-minimal-basic:      ✓ 
TYPE: sed:          ✓ 
== REGEX FEATURE: {} 
TYPE: awk:          - 
TYPE: egrep:          ✓ 
TYPE: ed:           - 
TYPE: emacs:          - 
TYPE: gnu-awk:         ✓ 
TYPE: grep:          - 
TYPE: posix-awk:         ✓ 
TYPE: posix-basic:        - 
TYPE: posix-egrep:        ✓ 
TYPE: posix-extended:        ✓ 
TYPE: posix-minimal-basic:      - 
TYPE: sed:          - 
== REGEX FEATURE: \+ 
TYPE: awk:          - 
TYPE: egrep:          - 
TYPE: ed:           ✓ 
TYPE: emacs:          - 
TYPE: gnu-awk:         - 
TYPE: grep:          ✓ 
TYPE: posix-awk:         - 
TYPE: posix-basic:        ✓ 
TYPE: posix-egrep:        - 
TYPE: posix-extended:        - 
TYPE: posix-minimal-basic:      - 
TYPE: sed:          ✓ 
== REGEX FEATURE: + 
TYPE: awk:          ✓ 
TYPE: egrep:          ✓ 
TYPE: ed:           - 
TYPE: emacs:          ✓ 
TYPE: gnu-awk:         ✓ 
TYPE: grep:          - 
TYPE: posix-awk:         ✓ 
TYPE: posix-basic:        - 
TYPE: posix-egrep:        ✓ 
TYPE: posix-extended:        ✓ 
TYPE: posix-minimal-basic:      - 
TYPE: sed:          - 
== REGEX FEATURE: \b 
TYPE: awk:          - 
TYPE: egrep:          ✓ 
TYPE: ed:           ✓ 
TYPE: emacs:          ✓ 
TYPE: gnu-awk:         ✓ 
TYPE: grep:          ✓ 
TYPE: posix-awk:         - 
TYPE: posix-basic:        ✓ 
TYPE: posix-egrep:        ✓ 
TYPE: posix-extended:        ✓ 
TYPE: posix-minimal-basic:      ✓ 
TYPE: sed:          ✓ 
== REGEX FEATURE: \< \> 
TYPE: awk:          - 
TYPE: egrep:          ✓ 
TYPE: ed:           ✓ 
TYPE: emacs:          ✓ 
TYPE: gnu-awk:         ✓ 
TYPE: grep:          ✓ 
TYPE: posix-awk:         - 
TYPE: posix-basic:        ✓ 
TYPE: posix-egrep:        ✓ 
TYPE: posix-extended:        ✓ 
TYPE: posix-minimal-basic:      ✓ 
TYPE: sed:          ✓ 
== REGEX FEATURE: [:digit:] 
TYPE: awk:          ✓ 
TYPE: egrep:          ✓ 
TYPE: ed:           ✓ 
TYPE: emacs:          - 
TYPE: gnu-awk:         ✓ 
TYPE: grep:          ✓ 
TYPE: posix-awk:         ✓ 
TYPE: posix-basic:        ✓ 
TYPE: posix-egrep:        ✓ 
TYPE: posix-extended:        ✓ 
TYPE: posix-minimal-basic:      ✓ 
TYPE: sed:          ✓ 
== REGEX FEATURE: \d 
TYPE: awk:          - 
TYPE: egrep:          - 
TYPE: ed:           - 
TYPE: emacs:          - 
TYPE: gnu-awk:         - 
TYPE: grep:          - 
TYPE: posix-awk:         - 
TYPE: posix-basic:        - 
TYPE: posix-egrep:        - 
TYPE: posix-extended:        - 
TYPE: posix-minimal-basic:      - 
TYPE: sed:          - 
== REGEX FEATURE: \s 
TYPE: awk:          ✓ 
TYPE: egrep:          ✓ 
TYPE: ed:           - 
TYPE: emacs:          ✓ 
TYPE: gnu-awk:         ✓ 
TYPE: grep:          - 
TYPE: posix-awk:         ✓ 
TYPE: posix-basic:        - 
TYPE: posix-egrep:        ✓ 
TYPE: posix-extended:        ✓ 
TYPE: posix-minimal-basic:      - 
TYPE: sed:          - 
=================== BSD find =================== 
== REGEX FEATURE: \{\} 
TYPE: basic:          ✓ 
TYPE: extended:         - 
== REGEX FEATURE: {} 
TYPE: basic:          - 
TYPE: extended:         ✓ 
== REGEX FEATURE: \+ 
TYPE: basic:          - 
TYPE: extended:         - 
== REGEX FEATURE: + 
TYPE: basic:          - 
TYPE: extended:         ✓ 
== REGEX FEATURE: \b 
TYPE: basic:          - 
TYPE: extended:         - 
== REGEX FEATURE: \< \> 
TYPE: basic:          - 
TYPE: extended:         - 
== REGEX FEATURE: [:digit:] 
TYPE: basic:          ✓ 
TYPE: extended:         ✓ 
== REGEX FEATURE: \d 
TYPE: basic:          - 
TYPE: extended:         - 
== REGEX FEATURE: \s 
TYPE: basic:          - 
TYPE: extended:         ✓ 
+0

работал как шарм !!, он работает даже без '-типа d' – ADPK

+0

@ADPK: рад его слышать; да, если шаблон имени достаточно конкретный, вам не нужно строго '-type d', но добавление его будет способствовать производительности, потому что' find' будет смотреть только на каталоги. – mklement0

-1

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

dirname "/path/20161128-20:34:33:432813246/data.txt" 

даст вам

/path/20161128-20:34:33:432813246 

Если вы действительно хотите регулярное выражение, попробуйте следующее:

\d{8}-\d{2}:\d{2}:\d{2}:\d{9} 
+2

Я чувствую, что это не может быть ответом, поскольку вопрос был более конкретным при достижении шаблона или правильного -regex. – Deepak

+0

Учитывая, что ОП не показывал попыток определить регулярное выражение в вопросе, меня не удивило бы, если это именно то, что они искали. – chepner

+1

OP использует '' * data.txt'' как _incidental example_ шаблона, который работает, но намерение явно соответствует именам каталогов напрямую, и чтобы 'find' выводил пути каталога напрямую (as против того, что нужно было применить «dirname» после факта). Что касается вашего регулярного выражения: (a) Ни GNU, ни BSD 'find' поддерживают ярлык символьного класса' \ d' и (b) для использования с '-regex', должен быть сопоставлен путь _entire_, а не только часть имени файла , – mklement0