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

I have these:

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

I wanted to find 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?

This question is related to shell unix grep

The answer is


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.


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

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

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

I'd prefer:

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

cheers


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

grep -F ABB.log a.tmp

similarly with awk

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

Works for me:

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

\b indicates/sets boundaries.

Seems to work pretty fast


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

grep -w "ABB.log " a.tmp

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 is with HPUX, if the content of the files has space between words, use this:

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


Examples related to shell

Comparing a variable with a string python not working when redirecting from bash script Get first line of a shell command's output How to run shell script file using nodejs? Run bash command on jenkins pipeline Way to create multiline comments in Bash? How to do multiline shell script in Ansible How to check if a file exists in a shell script How to check if an environment variable exists and get its value? Curl to return http status code along with the response docker entrypoint running bash script gets "permission denied"

Examples related to unix

Docker CE on RHEL - Requires: container-selinux >= 2.9 What does `set -x` do? How to find files modified in last x minutes (find -mmin does not work as expected) sudo: npm: command not found How to sort a file in-place How to read a .properties file which contains keys that have a period character using Shell script gpg decryption fails with no secret key error Loop through a comma-separated shell variable Best way to find os name and version in Unix/Linux platform Resource u'tokenizers/punkt/english.pickle' not found

Examples related to grep

grep's at sign caught as whitespace cat, grep and cut - translated to python How to suppress binary file matching results in grep Linux find and grep command together Filtering JSON array using jQuery grep() Linux Script to check if process is running and act on the result grep without showing path/file:line How do you grep a file and get the next 5 lines How to grep, excluding some patterns? Fast way of finding lines in one file that are not in another?