120

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?

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
Johnyy
  • 2,056
  • 3
  • 22
  • 28

12 Answers12

196
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.

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
117

Simply specify the regexp anchors.

grep '^ABB\.log$' a.tmp
mehmet
  • 7,720
  • 5
  • 42
  • 48
user562374
  • 3,817
  • 1
  • 22
  • 19
23

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

grep -w "ABB.log " a.tmp
Taryn
  • 242,637
  • 56
  • 362
  • 405
PranavKN
  • 339
  • 3
  • 3
3

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
Scrutinizer
  • 9,608
  • 1
  • 21
  • 22
2

similarly with awk

 awk '/^ABB\.log$/' file
ghostdog74
  • 327,991
  • 56
  • 259
  • 343
1

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
Community
  • 1
  • 1
Jahid
  • 21,542
  • 10
  • 90
  • 108
  • Did you actually experience that -F was missing in your case? If so, can you please say which case that was? – hakre Aug 08 '15 at 14:35
  • @hakre Did you read my answer completely? I explained (pretty clearly) why `-F` won't be needed if the `.` is escaped properly. – Jahid Aug 08 '15 at 14:41
  • Sure. Sure, I'm just asking: Was `-F` available when you wrote this? If not, which system were you using? I couldn't find that information in your answer so far, which even now is the case when I re-read it again. So really sure, I read your answer completely at least twice. ;) – hakre Aug 08 '15 at 15:04
  • @hakre Of course `-F` was available. ( I did say: "or use `-F` flag with `grep`") – Jahid Aug 08 '15 at 15:58
  • Thanks for the insight. Just one littel question remains: If `-F` is the answer, why bother about escaping? What's your opinion about that? – hakre Aug 08 '15 at 16:03
  • @hakre It is meant to be an explanation why OPs attempt as well as other answers using `.` without `-F` is wrong. And it also specifies that, if your requirement is not much, you can just escape the `.` without using `-F`. – Jahid Aug 08 '15 at 16:24
  • For that, your answer starts with a pretty weird wording. It sounds like an addition to another answer which is far superior in it's simplicity and stability so I wonder if it's really worth to add to it. But thanks for your feedback. And for what it counts: if your requirement is not much, you don't even need to escape the dot, it also matches itself. – hakre Aug 08 '15 at 16:31
  • And speaking of escaping, just see the accepted answer which does escaping. You either want to use switches or you want to formulate a pattern. I don't see why you should bother to do both in this case. But tha's just my 2 cents. – hakre Aug 08 '15 at 16:32
  • @hakre `you don't even need to escape the dot, it also matches itself` It also matches **any** character which obviously OP doesn't want. – Jahid Aug 09 '15 at 03:19
  • @hakre and also using the `-x` switch is not the main point here. If you don't want that, then simply use `^` and `$` as the accepted answer. The point I am trying to make is, if you want to match `.` (not **any** character) then escape it or use `-F` to make the pattern a fixed string (not a regex). – Jahid Aug 09 '15 at 03:28
  • Like I commented. Both has been answered exactly that way years ago. What has left to me was wondering about using `-F` with a fixed string starting with a dash. – hakre Aug 09 '15 at 06:41
  • @hakre once again, It is meant to be an explanation (with test example) why either `-F` or or escaping the `.` is necessary in this case, which obviously all other answers are missing (the explanation). And I don't see where you are going with `a fixed string starting with a dash` sentence. – Jahid Aug 09 '15 at 13:29
  • And how do I then escape the letter "`-`" with `-F` usage? That's missing for me in the explanation. – hakre Aug 09 '15 at 13:55
  • @hakre That's entirely a different question. You might want to start a new topic. `with -F usage`? don't be mistaken, a single `-` may work without `-F` graciously but that's not the solution for that. Try `echo "-foo" |grep "-foo"`. It will show error. The proper solution will be to use `--` with grep i.e `grep -- "-foo"` or `grep -F -- "-foo"` etc... – Jahid Aug 09 '15 at 15:50
  • Oh if you think that's a different explanation, then I can see why you didn't put it with the explanations you added here. I think it's worth the edit to make the usage clear in the -F answer given. – hakre Aug 09 '15 at 15:59
  • @hakre Well, OP never mentioned about something like that nor it seems to be in his concern, so it never came to me if someone would really try to find that in my answer. Anyway, respected your curiosity and added an extra explanation for that. – Jahid Aug 09 '15 at 16:33
  • Is your answer about the OP at all? I thought you mentioned you were concerned to leave explanations to other answers.... . Nevertheless, I think it would be worth if you're concerned about explaining to explain this as well. – hakre Aug 09 '15 at 16:35
  • @hakre none of the answers talks about a dash `-`, do they? – Jahid Aug 09 '15 at 16:37
  • And existing answers already show that escaping the dot makes a pattern, don't they? – hakre Aug 09 '15 at 16:47
  • I never had doubt in your clearness, I just was looking for feedback. Thanks for your time. – hakre Aug 09 '15 at 17:20
1

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

grep -F ABB.log a.tmp
-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
    $
-2

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

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

-2

Works for me:

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

\b indicates/sets boundaries.

Seems to work pretty fast

bschlueter
  • 3,817
  • 1
  • 30
  • 48
Surya
  • 11,002
  • 4
  • 57
  • 39
  • 1
    This also matches any line that contains `search_word` separated by word boundaries. For example, it would match the line, "foo search_word bar". – Rohan Singh Feb 18 '19 at 15:24
-3

I'd prefer:

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

cheers

-4

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
bschlueter
  • 3,817
  • 1
  • 30
  • 48
Jonathan
  • 1,498
  • 2
  • 20
  • 41
  • 1
    This will only match if the leading `\W` is satisfied, which is any non whitespace character, so `xABBxlog`. – bschlueter Dec 24 '17 at 02:47