开发者

How to make grep only match if the entire line matches?

开发者 https://www.devze.com 2023-02-05 13:00 出处:网络
I have these: $ cat a.tmp ABB.log ABB.log.122 ABB.log.123 I wanted to f开发者_运维技巧ind a exact match of ABB.log.

I have these:

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

I wanted to f开发者_运维技巧ind a exact match of ABB.log.

But when I did

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

it shows all of them.

Can I get what I wanted using grep?


grep -Fx ABB.log a.tmp

From the grep man page:

-F, --fixed-strings
Interpret PATTERN as a (list of) fixed strings
-x, --line-regexp
Select only those matches that exactly match the whole line.


Simply specify the regexp anchors.

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


Here is what I do, though using anchors is the best way:

grep -w "ABB.log " a.tmp


Most suggestions will fail if there so much as a single leading or trailing space, which would matter if the file is being edited by hand. This would make it less susceptible in that case:

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

A simple while-read loop in shell would do this implicitly:

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


similarly with awk

 awk '/^ABB\.log$/' file


I intend to add some extra explanation regarding the attempts of OP and other answers as well.

You can use John Kugelmans' solution like this too:

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

quoting the string and escaping the dot (.) makes it to not need the -F flag any more.

You need to escape the . (dot) (because it matches any character (not only .) if not escaped) or use the -F flag with grep. -F flag makes it a fixed string (not a regex).

If you don't quote the string, you may need double backslash to escape the dot (.):

grep -x ABB\\.log a.tmp


Test:

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


Note:

  1. -x forces to match the whole line.
  2. Answers using a non escaped . without -F flag are wrong.
  3. You can avoid -x switch by wrapping your pattern string with ^ and $. In this case make sure you don't use -F, instead escape the ., because -F will prevent the regex interpretation of ^ and $.


EDIT: (Adding extra explanation in regards of @hakre ):

If you want to match a string starting with -, then you should use -- with grep. Whatever follows -- will be taken as an input (not option).

Example:

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


This worked well for me when trying to do something similar:

grep -F ABB.log a.tmp


    $ 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
    $


This is with HPUX, if the content of the files has space between words, use this:

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


Works for me:

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

\b indicates/sets boundaries.

Seems to work pretty fast


I'd prefer:

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

cheers


I needed this feature, but also wanted to make sure I did not return lines with a prefix before the ABB.log:

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

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

精彩评论

暂无评论...
验证码 换一张
取 消