egrep b не распознает одинарную кавычку

#regex #grep

#регулярное выражение #grep

Вопрос:

Я пытаюсь перечислить все слова из 3 букв в файле, используя egrep.

Пример ввода;

коснитесь

ремень

меч

обрыв

не удается

может

не


Регулярное выражение;

egrep "b[a-zA-Z]{3}b"

Я получаю список слов из 3 букв, но почему в результатах не может отображаться?

Редактировать

Я получил ответ на свой первоначальный вопрос, и теперь я использую;

egrep '^[a-zA-Z]{3}$'

Это работает, потому что у меня есть только 1 слово в строке. Теперь мой вопрос обновлен, потому что этот ответ немного хрупкий.

Как бы я искал слова из 3 букв, если бы ввод был не по 1 слову в строке, а вместо этого в строках и абзацах?

Комментарии:

1. вероятно, потому, что ' считается границей слова, а в лингвистических терминах это can not ДВА слова из трех букв.

2. Да, в нем есть can и not, перечисленные отдельно, но я не хочу can’t! Разве я не использую ^ и $ вместо b?

3. Можете ли вы опубликовать пример ввода и ожидаемый результат?

4. если каждое слово в строке отдельно, то вам не нужны границы слов. /^...$/ помогло бы.

5. b соответствует везде, где символ word находится рядом с символом, не являющимся словом. n это символ слова ' , не являющийся символом слова, поэтому он совпадает между ними.

Ответ №1:

Если в строке несколько слов, вы не можете использовать привязки.

Если ваш grep поддерживает -P опцию (PCRE), тогда вы можете использовать регулярное выражение для просмотра:

 grep -oiP 'b[a-z]{3}(?=s|$)' file
  

Если -P недоступно, вы можете использовать:

 grep -oiE 'b[a-z]{3}(s|$)' file
  

во втором grep будет пробел в конце. Если вы хотите удалить и это, используйте:

 grep -oiE 'b[a-z]{3}(s|$)' file | awk '{print $1}'
  

В качестве альтернативы вот awk решение для печати всех трех буквенных полей:

 awk '{for (i=1; i<=NF; i  ) if (length($i)==3) print $i}' file
  

Если у вас есть gnu awk , вы можете сделать это еще короче:

 awk -v RS='[[:space:]]' 'length($0) == 3' file
  

Комментарии:

1. awk Ответ тот, который я хочу! Это общее решение, которое я могу использовать где угодно! Спасибо

2. вы можете использовать -w опцию для сопоставления только слов… grep -woiE '[a-z]{3}' или даже grep -woi '[a-z][a-z][a-z]'

3. @Sundeep: -w также найдет can в can't то, что OP не хочет.

4. вы правы, пропустили этот момент… awk решение кажется лучшим, поскольку такие имена, как F'nor , также будут учтены…

Ответ №2:

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

 egrep -i '^[a-z]{3}$' | sort
  

Проблема с вашим кодом заключается в том, что b совпадение между любым символом word и несловесным символом ' является несловесным символом.

Комментарии:

1. Пример вывода согласуется с этим предположением. Он не использует -o , но все состоит всего из одного слова в строке.

2. или используйте -x опцию, которая соответствует только целой строке