Части совпадения в регулярном выражении с egrep

#regex #grep

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

Вопрос:

Мне было интересно, могу ли я с помощью egrep ((GNU grep) 2.5.1) выделить часть совпадающего текста, что-то вроде:

 grep '^([a-zA-Z.-] )[0-9] ' ./file.txt
  

Таким образом, я получаю только ту часть, которая совпала, между скобками, что-то вроде

 house.com
  

Вместо целой строки, как я обычно получаю:

 house.com112
  

Предполагая, что у меня есть строка с house.com112 в моем file.txt.

(На самом деле это регулярное выражение — всего лишь пример, я просто хочу знать, могу ли я напечатать только часть всей строки.)

Я знаю, что на некоторых языках, таких как PHP, Perl или даже AWK, я могу, но я не знаю, смогу ли я с egrep.

Заранее благодарю вас!

Ответ №1:

Используется sed для изменения результата после того, как grep нашел совпадающие строки:

 grep '^[a-zA-Z.-] [0-9] ' ./file.txt | sed 's/[0-9] $//'
  

Или, если вы хотите придерживаться только grep, вы можете использовать grep с переключателем -o вместо sed:

 grep '^[a-zA-Z.-] [0-9] ' ./file.txt | grep -o '[a-zA-Z.-] '
  

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

1. Хорошо, спасибо всем, это сработало, но все вы были правы, мне пришлось обработать выходные данные grep.

Ответ №2:

возможно, вы захотите попробовать флаги -o, -w в grep. egrep «устарел», поэтому используйте grep -E .

 $ echo "test house.com house.com112"| grep -Eow "house.com"
house.com
  

Основная идея состоит в том, чтобы просмотреть каждое слово и проверить на равенство.

 $ echo "test house.com house.com112"| awk '{for(i=1;i<=NF;i  ){ if($i=="house.com") print $i}}'
house.com
  

Ответ №3:

Первая часть вашего регулярного выражения является более общей, чем вторая половина, и поскольку является жадным, вторая [0-9] будет никогда ничему не сопоставлять совпадают только с последней цифрой (спасибо Paul). Если вы можете сделать свою первую половину более конкретной (например, если вы знаете, что она закончится в TLD), вы могли бы это сделать.

Существует удивительно классный инструмент под названием ack, который по сути является grep с регулярными выражениями perl. Я не уверен, возможно ли это использовать в вашем случае, но если вы можете делать то, что хотите в perl, вы можете сделать это с помощью ack.

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

Почему бы просто не удалить конец регулярного выражения? Есть ли ложные срабатывания, если вы это сделаете? Если вы, вы могли бы снова передать результаты в egrep только с первой половиной регулярного выражения.

Похоже, это то, о чем вы спрашиваете: Кроме того, на тот случай, если вы не знаете об этом, флаг -o выведет только совпадающую часть заданной строки.

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

1. О, да, вы правы, это был дурацкий пример. Сейчас я собираюсь измениться. Редактировать: я уже изменил, что-то вроде этого.

2. 1 для подтверждения, хотя [0-9] должен соответствовать как минимум 1 символу, как я уверен, вы понимаете.

Ответ №4:

Используйте предварительный просмотр регулярного

 $ echo 'house.com112' | grep -Po '([a-zA-Z.] )(?=d )'
house.com