如何使grep仅在整行匹配时才匹配?


103

我有这些:

$ 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获得想要的东西吗?

Answers:


105

只需指定regexp锚。

grep '^ABB\.log$' a.tmp

2
两个锚(^和$)都是必需的。
user562374 2011年

2
好一个!如果我使用正则表达式来匹配文件?“ grep -f模式a.tmp”?
green69 2013年

@ green69迟了几年,但是您可以在将模式传递给grep之前使用sed添加锚点:sed -r "s/^(.*)$/^\1$/" patterns.txt | egrep -f - a.tmp
随机

155
grep -Fx ABB.log a.tmp

从grep手册页:

-F,--fixed-strings将
PATTERN解释为固定字符串的(列表)
-x,--
line -regexp仅选择与整行完全匹配的那些匹配项。


2
不幸的是无法使用-F。
约翰尼2011年

@Johnyy不-F?您在Solaris上吗?如果需要,请使用/usr/xpg4/bin/grep
审问者

9
我在grepbash脚本中使用,并且此选项比接受的答案中建议的使用正则表达式更好。因为我在要搜索的变量中有一些特殊字符(例如.),所以在使用命令时不必转义它们。
Gustavo Straube

1
IMO的最佳答案,因为它允许特殊字符而不会转义
ReneGAED

1
这样比较好,因为它也适用于变量。
ybenjira

23

这是我的工作,尽管使用锚点是最好的方法:

grep -w "ABB.log " a.tmp

像这样一个..它将返回第一行匹配
user765443

1
这需要在后面ABB.log加上一个空格,这不是通常的情况,即,大多数情况下它将失败。
Jahid 2015年

3

如果只有一个前导或尾随空格,则大多数建议将失败,如果手动编辑文件将很重要。在这种情况下,这将使其不那么容易受到攻击:

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

Shell中的一个简单的while读取循环将隐式地执行此操作:

while read file
do 
  case $file in
    (ABB.log) printf "%s\n" "$file"
  esac
done < a.tmp


1

我打算对OP的尝试以及其他答案进行一些补充说明。

您也可以使用John Kugelmans的解决方案,例如:

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会阻止^and 的正则表达式解释$


编辑:( 添加有关@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

您实际上是否遇到过-F在您的情况下不见了?如果是这样,请您说那是哪种情况?
2015年

@hakre您是否完整阅读了我的答案?我(很清楚地)解释了-F,如果.正确地逃脱了,为什么不需要。
Jahid 2015年

当然。当然,我只是问:-F写这篇文章时有空吗?如果没有,您使用的是哪个系统?到目前为止,我在您的答案中找不到该信息,即使是现在,当我再次阅读该信息时,也是如此。可以肯定的是,我至少读了两次完整的答案。;)
hakre 2015年

@hakre当然-F可用。(我确实说过:“或将-F标记与一起使用grep”)
Jahid 2015年

感谢您的见解。剩下的一个小问题仍然是:如果-F是答案,为什么还要逃跑呢?您对此有何看法?
hakre


-1
    $ cat venky
    ABB.log
    ABB.log.122
    ABB.log.123

    $ cat venky | grep "ABB.log" | grep -v "ABB.log\."
    ABB.log
    $

    $ cat venky | grep "ABB.log.122" | grep -v "ABB.log.122\."
    ABB.log.122
    $

1
这也将匹配以ABB.log结尾的文件,并且点应转义。
审查者

-1

为我工作

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

\b 指示/设置边界。

似乎工作很快


这也匹配任何包含search_word由单词边界分隔的行。例如,它将与“ foo search_word bar”行匹配。
罗汉·辛格

-2

这与HPUX一起使用,如果文件的内容在单词之间有空格,请使用以下命令:

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


OP希望匹配整行,而不是行中以空格分隔的单词。
基思·汤普森


-3

我需要此功能,但还想确保我没有在ABB.log之前返回带有前缀的行:

  • ABB.log
  • ABB.log.122
  • ABB.log.123
  • 123ABB.log

grep "\WABB.log$" -w a.tmp

仅当\W满足前导时(这是任何非空格字符),此属性才匹配xABBxlog
bschlueter
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.