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 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:
-x
forces to match the whole line.- Answers using a non escaped
.
without-F
flag are wrong. - 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
精彩评论