поведение пробелов в регулярном выражении grep

87

У меня есть текстовый файл, содержащий что-то вроде:

12,34 EUR 
 5,67 EUR
 ...

Перед «EUR» стоит один пробел, и я игнорирую 0, XX EUR.

Я старался:

grep '[1-9][0-9]*,[0-9]\{2\}\sEUR' => didn't match !

grep '[1-9][0-9]*,[0-9]\{2\} EUR' => worked !

grep '[1-9][0-9]*,[0-9]\{2\}\s*EUR' => worked !

grep '[1-9][0-9]*,[0-9]\{2\}\s[E]UR' => worked !

Может кто-нибудь объяснить мне, пожалуйста, почему я не могу использовать, \sно \s*и \s[E]сопоставил?

ОС: Ubuntu 10.04, grep v2.5

Milde
источник

Ответы:

122

Это похоже на разницу в поведении при обработке \sмежду grep 2.5 и более новыми версиями (ошибка в старой grep?). Я подтверждаю ваш результат с помощью grep 2.5.4, но все четыре ваших grep работают при использовании grep 2.6.3 (Ubuntu 10.10).

Заметка:

GNU grep 2.5.4
echo "foo bar" | grep "\s"
   (doesn't match)

в то время как

GNU grep 2.6.3
echo "foo bar" | grep "\s"
foo bar

Вероятно, меньше проблем (как \sне задокументировано):

Both GNU greps
echo "foo bar" | grep "[[:space:]]"
foo bar

Мой совет - избегать использования \s... использовать [ \t]*или [[:space:]]или что-то подобное.

Камаль
источник
24
Или просто [:space:], например. вот так:cat file | grep "[[:space:]]"
Кирилл Киров
в соответствии с этим запросом на ошибку mail-archive.com/bug-grep@gnu.org/msg02686.html это кажется ошибкой в ​​более новой версии grep (другая точка зрения), но почему последний оператор совпадает?
Milde
1
@Milde, обратите внимание на следующий пост mail-archive.com/bug-grep@gnu.org/msg02689.html, где этот отчет об ошибке был помечен как недопустимый и закрытый (так что это не считается ошибкой в ​​более новой версии grep).
Kamal
2
@Milde, ни одна из изученных мною grep документации (старая или новая) вообще не относится к ней \s. Я бы сказал, что его поведение «неопределенно». Вместо этого используйте [: space:], который работает, как описано в старом и новом grep.
Kamal
спасибо, я буду использовать [: space:] в будущем, чтобы избежать проблемы
Milde