How can I grep for a string that begins with a dash/hyphen?
Asked Answered
N

12

510

I want to grep for the string that starts with a dash/hyphen, like -X, in a file, but it's confusing this as a command line argument.

I've tried:

grep "-X"
grep \-X
grep '-X'
Niacin answered 11/3, 2010 at 19:14 Comment(0)
T
680

Use:

grep -- -X

Documentation

Related: What does a bare double dash mean? (thanks to nutty about natty).

Toting answered 11/3, 2010 at 19:24 Comment(7)
for those of us wondering at this stage what -- means or does: unix.stackexchange.com/questions/11376/…Caboose
Works with The Silver Searcher (ag) as well.Unreasonable
If you want to use with variable having spaces you should use something like this: ARGS="-a -b -c" grep -- "$ARGS"Trinhtrini
@Trinhtrini Or just, grep -- "--name awesome".Yod
What if I want to grep for -X followed by a space? (or a new line)Peasecod
Example: I want to do a case-insensitive (-i) search for -std= in my git repo. The following works: git grep -ni -- -std=Dichroite
grep -r <-other-options> -- "-X " ./ ..anything within quotes immediately after the -- (including spaces) will be considered part of the search string. If you put options before the -- then you can put as many options as you want, such as -r, etc.Preprandial
W
78

The dash is a special character in Bash as noted at http://tldp.org/LDP/abs/html/special-chars.html#DASHREF. So escaping this once just gets you past Bash, but Grep still has it's own meaning to dashes (by providing options).

So you really need to escape it twice (if you prefer not to use the other mentioned answers). The following will/should work

grep \\-X
grep '\-X'
grep "\-X"

One way to try out how Bash passes arguments to a script/program is to create a .sh script that just echos all the arguments. I use a script called echo-args.sh to play with from time to time, all it contains is:

echo $*

I invoke it as:

bash echo-args.sh \-X
bash echo-args.sh \\-X
bash echo-args.sh "\-X"

You get the idea.

Wooten answered 15/5, 2012 at 23:38 Comment(2)
I don't think - is a special character in Bash despite what the ABS guide says. Bash doesn't process arguments beginning with - any differently than others. The command or built-in that Bash subsequently calls will handle arguments beginning with a dash however it sees fit. Most of the Bash built-ins and Linux and GNU commands handle -- as an option terminator. Use 'set -x' to see the commands and arguments that Bash uses before they will be executed, but after Bash has expanded escapes, globs, and braces. Grep is a confusing example because it does its own handling of backslash escapes.Randolphrandom
How can an answer that is so plain wrong get so many upvotes?Outwardbound
A
41

With GNU grep, grep -e -X will do the trick.

Association answered 11/3, 2010 at 19:16 Comment(6)
my grep doesn't have -e, very weirdNiacin
Available on solaris from /usr/xpg4/bin/grep, btw. Lots of more-complete utilities in that directory.Code
It worked under MinGW (MinGW doesn't support -P (but that is another story and does not apply here)).Dineric
>What if a pattern has a leading ‘-’? grep -e '--cut here--' * searches for all lines matching ‘--cut here--’. Without -e, grep would attempt to parse ‘--cut here--’ as a list of options.Poseur
This answer should be the accepted one since it allows putting a list of filenames to search into after the pattern. The double dash variant only works with a stream from standard input.Pretermit
This is correct. man grep says about -e: "This option can be used to protect a pattern beginning with “-”.Outwardbound
O
33
grep -- -X
grep \\-X
grep '\-X'
grep "\-X"
grep -e -X
grep [-]X
Oresund answered 11/3, 2010 at 19:14 Comment(0)
F
8

I dont have access to a Solaris machine, but grep "\-X" works for me on linux.

Forsooth answered 11/3, 2010 at 19:31 Comment(0)
P
6

The correct way would be to use "--" to stop processing arguments, as already mentioned. This is due to the usage of getopt_long (GNU C-function from getopt.h) in the source of the tool.

This is why you notice the same phenomena on other command-line tools; since most of them are GNU tools, and use this call,they exhibit the same behavior.

As a side note - getopt_long is what gives us the cool choice between -rlo and --really_long_option and the combination of arguments in the interpreter.

Provoke answered 25/9, 2013 at 14:16 Comment(0)
A
5

If you're using another utility that passes a single argument to grep, you can use:

'[-]X'
Aorta answered 19/6, 2014 at 23:42 Comment(0)
O
2

you can use nawk

$ nawk '/-X/{print}' file
Oversexed answered 11/3, 2010 at 23:55 Comment(0)
E
1

On macOS/BSD:

grep -e "-X"

is enough.

Elwina answered 21/8, 2023 at 3:53 Comment(0)
Z
0

None of the answers not helped me (ubuntu 20.04 LTS).
I found a bit another option:

My case:

systemctl --help | grep -w -- --user

-w will match a whole word.
-- means end of command arguments (to mark -w as not part of the grep command)

Zoe answered 29/11, 2022 at 11:58 Comment(0)
T
-1

grep "^-X" file

It will grep and pick all the lines form the file. ^ in the grep"^" indicates a line starting with

Taliesin answered 2/1, 2016 at 1:32 Comment(2)
There’s already an answer which suggested that https://mcmap.net/q/73897/-how-can-i-grep-for-a-string-that-begins-with-a-dash-hyphen (posted more than a year ago)Gastroscope
The OP is looking for strings that starts with -, not lines.Ott
J
-3
ls -l | grep "^-"

Hope this one would serve your purpose.

Joan answered 12/12, 2014 at 9:18 Comment(1)
This expression catch only lines that begin with a dash. It does not complies with the initial question. He want to search for a string starting by a dash but the lines that contains this string did not necessary begin with a dash.In the initial question, the string beginning with a dash can be anywhere in the line.Hodge

© 2022 - 2024 — McMap. All rights reserved.