I'm trying to display files that contain


I tried like this

grep -l '!#abc'

but it doesn't work. Why?

Also, when I try something like

echo "#!a"

it retrieves

echo "#alias".

Can someone, please explain me what is happening here? What does #! in fact represent?


you have to write

grep \\!\\#abc <file>

you basically have to escape both the # and the !, this two characters have special meaning in pretty much any shell, read the manual of your shell to know more about them .

| improve this answer | |

Well, the grep: grep -l '!#abc' needs also a list of files to process:

grep -l '!#abc' ./*

works in all the files in the present directory.

The echo: echo "#!a" needs a little more of quoting, like:

$ echo '#!a'

$ echo '#'\!'a'

$ echo '#'\!a

$ echo "#!"a

$ echo "#"'!a'

$ echo $'#!a'

The '#' is the comment character. From LESS=+'/^ *COMMENTS' man bash:


In a non-interactive shell, or an interactive shell in which the  
interactive_comments option to the shopt builtin is enabled (see SHELL  
BUILTIN COMMANDS below), a word beginning with # causes that word and  
all remaining characters on that line to be  ignored. An interactive  
shell without the interactive_comments option enabled does not allow  
comments. The interactive_comments option is on by default in  
interactive shells.

Anything that follows it in one line is considered 'a comment' and not processed, like:

$ echo one # two three

If you want to avoid its effect, you need to quote it, or place it just after some other non-blank character:

$ echo one t# wo three
one t# wo three

The ! is the history "key character".
Just the tip of the Iceberg: From LESS=+'/^ *HISTORY EXPANSION' man bash:

History expansions are introduced by the appearance of the history expansion character, which is ! by default. Only backslash () and single quotes can quote the history expansion character, but the history expansion character is also treated as quoted if it immediately precedes the closing double quote in a double-quoted string.

So, for your last question: What does #! in fact represent?.

The answer is It depends. Depends on the surrounding characters as well.
Depends if it is quoted (and how is quoted) or not. And depends if it has preceding white space and/or trailing white space.

If correctly quoted, just the same characters. If not quoted with a leading space: a comment. If not quoted, no leading space, no trailing space: an history expansion.
If not quoted, no leading space, with a trailing space: the characters.

That, of course, is assuming that the options

shopt -p interactive_comments
shopt -po history

Are both set. Each controls the respective character (# and !) in interactive shells. In non-interactive shells, the comment character is always enforced, and history expansion is almost always not activated.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.