I am trying to searching a file to for text containing "[]" brackets. For example,
list[1];
i[ab1];
I tried grep -i \[[a-z||1-9]*\] myfile
. But it doesn't work. These square brackets are special characters. I don't know how to escaping there special meaning. Can anybody give any suggestion?
[
is a special character in a regular expression, since it is used to denote a range (just as you use it for in the subexpression [a-z||1-9]
). You need to escape it so that grep will interpret it as a literal [
character; you do this by preceeding it with a backslash.
However, backslashes are also escape characters in the shell. To pass a single backslash to grep, you need to double it on the shell command line! You also need to escape the |
characters and really should escape the *
character, since these are also special to the shell:
grep -i \\[[a-z\|\|1-9]\*\\] myfile
It gets a bit easier if you just enclose the whole string in double quote marks:
grep -i "\\[[a-z||1-9]*\\]" myfile
Note that you still need to double the backslashes, as they can escape characters in a quoted string too. Even better would be to use a string enclosed with single quotes, in which backslashes don't act as an escape:
grep -i '\[[a-z||1-9]*\]' myfile
You are not escaping enough. The shell interprets and peels off the backslashes before grep
sees them.
A good general guidance is to always put your regular expressions in single quotes.
grep -i '\[[a-z1-9]*\]' myfile
The ||
seemed like a misunderstanding so I took it out. Between square brackets you simply put one of each character which is allowed in the match.
The square brackets have a similar meaning in the shell, which is why the first backslash only escapes them from the shell, not from grep
. ls [*]
will find files named literally with a single asterisk, not all files, or all files whose name is in square brackets. (Using ls
here as an example with the caveat that you usually do not want to use ls
in scripts; and just ls
will list all files; and echo [*]
will also list all files matching the wildcard expression -- though in Bash out of the box, if you get no matches, the wildcard will not be expanded, and so the error message might confusingly suggest that the wildcard didn't work.)
Not quoting arguments can be very dangerous, because the outcome of an unexpected wildcard expansion will depend on which files exist in the current directory. Behold:
vnix$ echo '|' >myfile
vnix$ grep -i \[[a-z||1-9]*\] myfile
grep: brackets ([ ]) not balanced
-bash: 1-9]*]: command not found
vnix$ grep -i \[[a-z\|\|1-9]*\] myfile
vnix$ # Right. No matches. But watch:
vnix$ touch '[|]'
vnix$ grep -i \[[a-z\|\|1-9]*\] myfile
|
vnix$ # !?! WTF?
vnix$ printf '<%s>\n' grep -i \[[a-z\|\|1-9]*\] myfile
<grep>
<-i>
<[|]>
<myfile>
So -- the shell expanded the unquoted regular expression as a wildcard when there was a matching file and you ended up grepping for something else than what you thought you were.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With