"Недопустимый конец диапазона" Grep-ошибка или функция?

у меня есть эти три файла:

$ cat pattern-ok 
['-]
$ cat pattern-buggy 
[-']
$ cat text 
abc'def-ghi

и теперь, является ли следующая ошибка или функция regexp, которую я не знаю?

$ cat text | grep -f pattern-ok 
abc'def-ghi
$ cat text | grep -f pattern-buggy
grep: Invalid range end

Я использую:

$ grep --version | head -n 1
grep (GNU grep) 2.20

1 ответов


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

вы в основном делаете

grep "[\-']" file

это интерпретируется grep как вы предоставляете диапазон символов для проверки, например grep "[a-z]" file. Но диапазон от \ to ' является недопустимым, следовательно, ошибка.

а почему работает другой? Возможно, вы спрашиваете себя. Потому что то, что вы делаете:

grep "['\-]" file

в этом случае вы ищете либо символ ', \ или - в файле.

см. другой пример этого, где я хочу найти символы a, - или 3 в данной строке:

$ echo "23-2" | grep -o '[a-3]'
grep: Invalid range end
$ echo "23-2" | grep -o '[a3-]'
3
-
$ echo "23-2" | grep -o '[a3\-]'
3
-

Итак, основная проблема заключается в том, что вы используете выражение some character + - + another character внутри [] блок и он пытается читать как диапазон символов между some character и another character.


как вы можете его решить?

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

С man grep:

классы символов и Скобочные выражения

скобочное выражение-это список символов, заключенный в [ и]. Он соответствует любому символу в этом списке; если первый символ из списка есть каретка ^, то она соответствует любому символу не в список. Например, регулярное выражение [0123456789] соответствует ни в одной цифре.

в скобочном выражении,диапазон состоит из двух символы, разделенные дефисом. Он соответствует любому символу что между двух символов, с помощью языка сопоставление последовательности и набора символов. Например, в C по умолчанию locale, [a-d] эквивалентно [abcd]. Многие локали сортируют символы в порядке словаря, и в этих локалях [a-d] обычно не эквивалентно [abcd]; это может быть эквивалентно [aBbCcDd], для образец. Для получения традиционной интерпретации скобки выражения, вы можете использовать локаль C, установив LC_ALL переменная окружения к значению C.

наконец, определенные именованные классы символов предопределены внутри скобочные выражения, как следует. Их имена не требуют пояснений., и они [: alnum:], [: alpha:], [: cntrl:], [: digit:], [: graph:], [: lower:], [: print:], [: punct:], [: space:], [: upper:], и [:xdigit:]. Например, [[: alnum:]] означает класс символов цифры и Буквы в текущей локали. В локали C и ASCII кодировка набора символов, это то же самое, что и [0-9A-Za-z]. (Отмечать что скобки в этих именах классов являются частью символа имена и должны быть включены в добавление к скобкам, разделяющим выражение скобки.) Большинство мета-символов теряют свой особый смысл внутри скобочных выражений. Чтобы включить литерал ] поместите его первый в списке. Аналогично, чтобы включить литерал ^ поместите его куда угодно, только не в первую очередь. наконец, чтобы включить литерал-поместите его последний.