Как сделать так, чтобы grep совпадал только если вся строка совпадает? - PullRequest
91 голосов
/ 17 января 2011

У меня есть эти:

$ cat a.tmp
ABB.log
ABB.log.122
ABB.log.123

Я хотел найти точное соответствие ABB.log.

Но когда я сделал

$ grep -w ABB.log a.tmp
ABB.log
ABB.log.122
ABB.log.123

, он показывает их все.

Могу ли я получить то, что хотел, используя grep?

Ответы [ 12 ]

134 голосов
/ 17 января 2011
grep -Fx ABB.log a.tmp

Со страницы руководства grep:

-F, --fixed-strings
Интерпретировать PATTERN как (список) фиксированных строк
-x, --line-regexp
Выберите только те совпадения, которые точно соответствуют всей строке.

94 голосов
/ 17 января 2011

Просто укажите якоря регулярных выражений.

grep '^ABB\.log$' a.tmp
24 голосов
/ 13 марта 2012

Вот что я делаю, хотя использование якорей - лучший способ:

grep -w "ABB.log " a.tmp
2 голосов
/ 15 марта 2013

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

grep '^[[:blank:]]*ABB\.log[[:blank:]]*$' a.tmp

Простой цикл while-read в shell сделал бы это неявно:

while read file
do 
  case $file in
    (ABB.log) printf "%s\n" "$file"
  esac
done < a.tmp
2 голосов
/ 17 января 2011

аналогично с awk

 awk '/^ABB\.log$/' file
1 голос
/ 14 декабря 2015

Это хорошо сработало, когда я пытался сделать что-то подобное:

grep -F ABB.log a.tmp
1 голос
/ 12 июля 2015

Я намерен добавить некоторые дополнительные объяснения относительно попыток ОП и других ответов.

Вы можете использовать решение Джона Кугельманса , например, так:

grep -x "ABB\.log" a.tmp

цитирование строки и экранирование точки (.) приводят к тому, что ей больше не требуется флаг -F.

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

Если вы не заключите в кавычки строку, вам может понадобиться двойной обратный слеш для выхода из точки (.):

grep -x ABB\\.log a.tmp


Тест:
$ echo "ABBElog"|grep -x  ABB.log
ABBElog #matched !!!
$ echo "ABBElog"|grep -x  "ABB\.log"
#returns empty string, no match


Примечание:
  1. -x заставляет совпадать по всей строке.
  2. Ответы с использованиемнеправильный . без -F флаг неправильный.
  3. Вы можете избежать переключения -x, обернув строку шаблона с ^ и $.В этом случае убедитесь, что вы не используете -F, вместо этого экранируйте ., поскольку -F предотвратит интерпретацию регулярного выражения ^ и $.


РЕДАКТИРОВАТЬ: (Добавление дополнительных пояснений в отношении @hakre):

Если вы хотите сопоставить строку, начинающуюся с -, то вы должны использовать -- с grep.Что бы ни следовало, -- будет приниматься за вход (не опция).

Пример:

echo -f |grep -- "-f"     # where grep "-f" will show error
echo -f |grep -F -- "-f"  # whre grep -F "-f" will show error
grep "pat" -- "-file"     # grep "pat" "-file" won't work. -file is the filename
0 голосов
/ 11 мая 2016

Работает для меня :

grep "\bsearch_word\b" text_file > output.txt  

\b указывает / устанавливает границы.

Кажется, работает довольно быстро

0 голосов
/ 14 июля 2014

Это с HPUX, если содержимое файлов имеет пробел между словами, используйте это:

egrep "[[:space:]]ABC\.log[[:space:]]" a.tmp

0 голосов
/ 04 апреля 2013

Я бы предпочел:

str="ABB.log"; grep -E "^${str}$" a.tmp

ура

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...