2016-06-28 4 views
0

Я пытаюсь grep шаблон из файлов с использованием egrep и regex без успеха.Grep имя файла с определенным рисунком подчеркивания

Что мне нужно, чтобы получить файл, например, с именем Конвенции:

xx_code_lastname_firstname_city.doc 

Код должен иметь по крайней мере 3 цифр, LastName и FirstName и город могут варьироваться по размеру

Я пытаюсь код ниже, но это не удается добиться того, что я хочу:

ls -1 | grep -E "[xx_][A-Za-z]{3,}[_][A-Za-z]{2,}[_][A-Za-z]{2,}[_][A-Za-z]{2,}[.][doc|pdf]" 

это пытается получить стандартный xx_ от самого начало, то любой код, который имеет по крайней мере 3 слова и после этого у него должен быть другой знак подчеркивания и т. д. Может ли кто-нибудь помочь?

+0

Не используйте 'ls | grep' - см. http://mywiki.wooledge.org/ParsingLs –

+0

Можете ли вы указать, какую оболочку вы используете? Red Hat отправляет несколько - bash? МКШ? –

+2

BTW, '[xx_]' соответствует * одному символу *, либо 'x', либо' _'. –

ответ

5

Рассмотрим extglob следующим образом:

#!/bin/bash 
shopt -s extglob # turn on extended globbing syntax 

files=(xx_[[:alpha:]][[:alpha:]]+([[:alpha:]])_[[:alpha:]]+([[:alpha:]])_[[:alpha:]]+([[:alpha:]])_[[:alpha:]]+([[:alpha:]])[email protected](doc|docx|pdf)) 

[[ -e ${files[0]} ]] || -L ${files[0]} ]] && printf '%s\n' "${files[@]}" 

Это работает, потому что

[[:alpha:]][[:alpha:]]+([[:alpha:]]) 

... любая строка из трех или более алфавитных символов - два из них в явном виде, один из них с одним или более синтаксисом extglob +().


Аналогично,

@(doc|docx|pdf) 

... соответствует любому из этих трех конкретных строк.

+0

Просто используйте 'nullglob', выкапывайте уродливые' [[-e || -L]] 'трюк, и у вас будет то, что я предложил в комментарии':) '. –

+0

@gniourf_gniourf, я немного опасаюсь «nullglob», если мы не нажмем OP, чтобы сразу же отключить его - легко попасть в ловушки с командами, которые имеют поведение по умолчанию, если не заданы аргументы, а именно, почему nullglob по умолчанию для начала. –

+0

Затем используйте 'failglob'. Но настоятельно рекомендуется использовать глобусы. –

3

Итак, вы пытаетесь сопоставить литерал xx_? Начните свой шаблон с этой части.

xx_ 

Далее идут «3 цифры», которые вы пытаетесь сопоставить. Я собираюсь предположить, основываясь на вашем собственном регулярном выражении, что под «цифрами» вы подразумеваете символы (следовательно, классы символов [a-zA-Z]). Давайте сделаем квантификатор неживым, чтобы избежать непреднамеренного захвата.

xx_[a-zA-Z]{3,}? 

Для первой и последней частей я вижу, что вы указали переменную длину не менее двух символов. Давайте сделаем так, чтобы эти кванторы не были жадными, добавив символ ? после наших квантификаторов. Согласно вашему регулярному выражению, также похоже, что вы ожидаете, что ваша городская конструкция примет аналогичную форму с битами firstname и lastname. Тогда добавим все три.

xx_[a-zA-Z]{3,}?_[a-zA-Z]{2,}?_[a-zA-Z]{2,}?_[a-zA-Z]{2,}\. 

ПРИМЕЧАНИЕ: Мы не должны сделать город квантор нежадным, так как мы утверждали, что за ним следует буквальному ".", что мы не должны появляться нигде в тексте интересующие нас в сопоставлении. Обратите внимание, как это экранировано, потому что это метасимвол в синтаксисе regex.

Идет, наконец, расширение файла, которое имеет ваш пример как "docx". Я также вижу, что вы добавили "doc" и расширение "pdf" в ваше регулярное выражение. Давайте объединим все три из них.

xx_[a-zA-Z]{3,}?_[a-zA-Z]{2,}?_[a-zA-Z]{2,}?_[a-zA-Z]{2,}\.(docx?|pdf) 

Надеюсь, это сработает. Прокомментируйте, если вам нужно какое-либо разъяснение. Обратите внимание, как части "doc" и "docx" были сконденсированы в один элемент. Это не обязательно, но я думаю, что в этой форме он выглядит более преднамеренным. Он также может быть записан как (doc|docx|pdf). Немного повторяю на мой вкус.

+0

'\ w' не поддерживается' grep -E', с использованием синтаксиса POSIX ERE без расширений PCRE. (Некоторые версии GNU grep поддерживают 'grep -P', если они скомпилированы с поддержкой libpcre, но это очень необязательное расширение времени компиляции). –

+0

Хороший улов. Тогда я буду использовать специальные классы символов. Я всегда использую PCREs ... помогает мне поддерживать разумность. – wpcarro

+1

Лично я бы использовал '[[: alpha:]]' в предпочтении '[a-zA-Z]' - конечно, если вы находитесь в «C» locale, нет никакой разницы, но у нас есть читатели в других частях мира, с разными алфавитами. :) –