How to grep exact literal string (no regex)
Use fgrep
, it's the same as grep -F
(matches a fixed string).
Grepping for exact string while ignoring regex for dot character
fgrep
is the same as grep -F
. grep
also has the -x
option which matches against whole lines only. You can combine these to get what you want:
grep -Fx account.test file.txt
grep match exact substring ignoring regex syntax
Use grep -F or fgrep.
$ echo "1034" | grep -F $version # shouldn't match
$ echo "10.4" | grep -F $version
10.4
See man page:
-F, --fixed-strings
Interpret PATTERN as a list of fixed strings, separated
by newlines, any of which is to be matched.
I was looking for the term "literal match" or "fixed string".
(See also Using grep with a complex string and How can grep interpret literally a string that contains an asterisk and is fed to grep through a variable?)
Grep exact string not working when piped
If you have pgrep
, using pgrep -x mysqld
would be better choice than ps + grep
From man pgrep
pgrep, pkill - look up or signal processes based on name and other attributes
-x, --exact
Only match processes whose names (or command line if -f is specified) exactly match the pattern.
-l, --list-name
List the process name as well as the process ID. (pgrep only.)
-c, --count
Suppress normal output; instead print a count of matching processes. When count does not match any‐
thing, e.g. returns zero, the command will return non-zero value.
-n, --newest
Select only the newest (most recently started) of the matching processes.
Grep for literal strings
You can use grep for that, with the -F option.
-F, --fixed-strings PATTERN is a set of newline-separated fixed strings
Problem with using grep to match the whole word
Update: Using fgrep -x '/user/hemanth.a'
is probably a better solution here, as it avoids having to escape characters such as $
to prevent grep
from interpreting them as meta-characters. fgrep
performs a literal string match as opposed to a regular expression match, and the -x
option tells it to only match whole lines.
Example:
> cat testfile.txt
foo
foobar
barfoo
barfoobaz
> fgrep foo testfile.txt
foo
foobar
barfoo
barfoobaz
> fgrep -x foo testfile.txt
foo
Original answer:
Try adding the $
regex metacharacter to the end of your grep
expression, as in:
echo $snapshottableDirs | tr -s ' ' '\n' | grep -w '/user/hemanth.a$'.
The $
metacharacter matches the end of the line.
While you're at it, you might also want to use the ^
metacharacter, which matches the beginning of the line, so that grep '/user/hemanth.a$'
doesn't accidentally also match something like /user/foo/user/hemanth.a
.
So you'd have this:
echo $snapshottableDirs | tr -s ' ' '\n' | grep '^/user/hemanth\.a$'.
Edit: You probably don't actually want the -w
here, so I've removed that from my answer.
Edit 2: @U. Windl brings up a good point. The .
character in a regular expression is a metacharacter that matches any character, so grep /user/hemanth.a
might end up matching things you're not expecting, such as /user/hemanthxa
, etc. Or perhaps more likely, it would also match the line /user/hemanth/a
. To fix that, you need to escape the .
character. I've updated the grep
line above to reflect this.
Update: In response to your question in the comments about how to escape a string so that it can be used in a grep
regular expression...
Yes, you can escape a string so that it should be able to be used in a regular expression. I'll explain how to do so, but first I should say that attempting to escape strings for use in a regex can become very complicated with lots of weird edge cases. For example, an escaped string that works with grep
won't necessarily work with sed
, awk
, perl
, bash's =~
operator, or even grep -e
.
On top of that, if you change from single quotes to double quotes, you might then have to add another level of escaping so that bash will expand your string properly.
For example, if you wanted to search for the literal string 'foo [bar]* baz$'
using grep
, you'd have to escape the [
, *
, and $
characters, resulting in the regular expression:
'foo \[bar]\* baz\$'
But if for some reason you decided to pass that expression to grep
as a double-quoted string, you would then have to escape the escapes. Otherwise, bash would interpret some of them as escapes. You can see this if you do:
echo "foo \[bar]\* baz\$"
foo \[bar]\* baz$
You can see that bash interpreted \$
as an escape sequence representing the character $
, and thus swallowed the \
character. This is because normally, in double quoted strings $
is a special character that begins a parameter expansion. But it left \[
and \*
alone because [
and *
aren't special inside a double-quoted string, so it interpreted the backslashes as literal \
characters. To get this expression to work as an argument to grep
in a double-quoted string, then, you would have to escape the last backslash:
# This command prints nothing, because bash expands `\$` to just `$`,
# which grep then interprets as an end-of-line anchor.
> echo 'foo [bar]* baz$' | grep "foo \[bar]\* baz\$"
# Escaping the last backslash causes bash to expand `\\$` to `\$`,
# which grep then interprets as matching a literal $ character
> echo 'foo [bar]* baz$' | grep "foo \[bar]\* baz\\$"
foo [bar]* baz$
But note that "foo \[bar]\* baz \\$"
will not work with sed
, because sed
uses a different regex syntax in which escaping a [
causes it to become a meta-character, whereas in grep
you have to escape it to prevent it from being interpreted as a meta-character.
So again, yes, you can escape a literal string for use as a grep
regular expression. But if you need to match literal strings containing characters that will need to be escaped, it turns out there's a better way: fgrep
.
The fgrep
command is really just shorthand for grep -F
, where the -F
tells grep
to match "fixed strings" instead of regular expression. For example:
> echo '[(*\^]$' | fgrep '[(*\^]$'
[(*\^]$
This works because fgrep
doesn't know or care about regular expressions. It's just looking for the exact literal string '[(*\^]$'
. However, this sort of puts you back at square one, because fgrep
will match on substrings:
> echo '/users/hemanth/dummy' | fgrep '/users/hemanth'
/users/hemanth/dummy
Thankfully, there's a way around this, which it turns out was probably a better approach than my initial answer, considering your specific needs. The -x
option to fgrep
tells it to only match the entire line. Note that -x
is not specific to fgrep
(since fgrep
is really just grep -F
anyway). For example:
> echo '/users/hemanth/dummy' | fgrep -x '/users/hemanth' # prints nothing
This is equivalent to what you would have gotten by escaping the grep
regex, and is almost certainly a better answer than my previous answer of enclosing your regex in ^
and $
.
Now, as promised, just in case you want to go this route, here's how you would escape a fixed string to use as a grep
regex:
# Suppose we want to match the literal string '^foo.\ [bar]* baz$'
# It contains lots of stuff that grep would normally interpret as
# regular expression meta-characters. We need to escape those characters
# so grep will interpret them as literals.
> str='^foo.\ [bar]* baz$'
> echo "$str"
^foo.\ [bar]* baz$
> regex=$(sed -E 's,[.*^$\\[],\\&' <<< "$str")
> echo "$regex"
\^foo\.\\ \[bar]\* baz\$
> echo "$str" | grep "$regex"
^foo.\ [bar]* baz$
# Success
Again, for the reasons cited above, I don't recommend this approach, especially not when fgrep -x
exists.
Is there an easy way to pass a raw string to grep?
If you are attempting to get grep
to use Extended Regular Expression syntax, the way to do that is to use grep -E
(aka egrep
). You should also know about grep -F
(aka fgrep
) and, in newer versions of GNU Coreutils, grep -P
.
Background: The original grep
had a fairly small set of regex operators; it was Ken Thompson's original regular expression implementation. A new version with an extended repertoire was developed later, and for compatibility reasons, got a different name. With GNU grep
, there is only one binary, which understands the traditional, basic RE syntax if invoked as grep
, and ERE if invoked as egrep
. Some constructs from egrep
are available in grep
by using a backslash escape to introduce special meaning.
Subsequently, the Perl programming language has extended the formalism even further; this regex dialect seems to be what most newcomers erroneously expect grep
, too, to support. With grep -P
, it does; but this is not yet widely supported on all platforms.
So, in grep
, the following characters have a special meaning: ^$[]*.\
In egrep
, the following characters also have a special meaning: ()|+?{}
. (The braces for repetition were not in the original egrep
.) The grouping parentheses also enable backreferences with \1
, \2
, etc.
In many versions of grep
, you can get the egrep
behavior by putting a backslash before the egrep
specials. There are also special sequences like \<\>
.
In Perl, a huge number of additional escapes like \w
\s
\d
were introduced. In Perl 5, the regex facility was substantially extended, with non-greedy matching *?
+?
etc, non-grouping parentheses (?:...)
, lookaheads, lookbehinds, etc.
... Having said that, if you really do want to convert egrep
regular expressions to grep
regular expressions without invoking any external process, try ${regex/pattern/substitution}
for each of the egrep
special characters; but recognize that this does not handle character classes, negated character classes, or backslash escapes correctly.
ag: search exact string, not a pattern
The option you're looking for is
-Q --literal: Do not parse PATTERN as a regular expression. Try to match it literally.
@ https://github.com/ggreer/the_silver_searcher/blob/master/doc/ag.1.md:
grep not consider dot in exact search
You can use a regex:
cat tlds.csv | grep -E ',com\.csv$'
In this way, you tell grep that you want only those lines that have a ,
before com.csv
, and nothing more after com.csv
.
You can also use
cat tlds.csv | grep -E '[^.]com\.csv$'
to tell grep that before com.csv
it's okay any char except for .
.
Anyway, if I can add a suggestion I wouldn't use cat
. grep can take your file as an argument, int this way:
grep -E '[^.]com\.csv$' tlds.csv
Here you can see why you should prefer not using cat
.
grep matches exact string or with wildcard
grep
uses regex for pattern matching. grep -w 'name1*'
would make it match zero or more 1
s, so name1
and name11
would match.
If it only matches name1
for you it's because you have a file named name1
in the directory and the unquoted name1*
will be interpreted by the shell (globbing). Always use quotes around your arguments that contain special characters. If you use a variable, always put "
around it.
To make it match any name starting with name1
, make it
grep -w 'name1.*' filename
.
means "any character".*
means "any character, zero or more times".
If the input comes from some external source where *
is used as a wildcard, you need to change that string before calling grep.
Example:
search_str='name1*'
new_search_str="$(sed 's/\*/.*/g' <<< "$search_str")"
grep -w "$new_search_str" filename
Related Topics
Redirecting Man Page Output to File Results in Double Letters in Words
Which Stack Is Used by Interrupt Handler - Linux
What Is Chained Irq in Linux, When Are They Need to Used
Count Files and Directories Using Shell Script
Checkpoint/Restart Using Core Dump in Linux
Errors in Make File:*** Missing Separator. Stop
How to Do Versioning of Shared Library
How to Launch Multiple Xterm Windows and Run a Command on Each, Leaving Each Window Open Afterward
A Way to Determine a Process'S "Real" Memory Usage, I.E. Private Dirty Rss
Shell Script Calls Sudo; How to Suppress the Password Prompt
How to Run Linux Docker Images on Windows Server 2016
How to Set Up My Linux X Terminal So That Emacs Has Access to 256 Colors
Linux Mail < File.Log Has Content-Type: Application/Octet-Stream (A Noname Attachment in Gmail)
Accessing Linux /Dev/Usb as Standard Files to Communicate with Usb Device
Run Command After 1 Hour in Linux
I Want to Use "Awk" or Sed to Print All the Lines That Start with "Comm=" in a File