When I use !
as a field separator e.g. awk -F!
it is giving error message bash: !: event not found
. Why? It is accepting awk -F"\!"
. Bash version 3.2.25

- 192
2 Answers
!
is the trigger character for Bash's history expansion. If that's enabled, something like !foo
on a command line gets expanded to the latest command that starts with foo
. Or if there is no such command line, the shell gives an error, like here.
It shouldn't do anything as the last character of a word, though. This actually works as you intended in all versions of Bash I tried:
$ echo 'aa!bb' | awk -F! '{print $1}'
aa
In more recent versions, !
also shouldn't do anything before an ending double-quote, so -F"!"
works in later versions, but not in 3.2.
A backslash or single-quotes will work to escape it, i.e. neither \!foo
nor '!foo'
would expand. Of course you could also stop it by disabling history expansion completely, with set +H
.
With double-quotes it's weirder. Within them, a backslash disables the history expansion but the backslash itself gets left in place:
$ printf '%s\n' "\!foo"
\!foo
In the case of awk -F"\!"
this works because awk itself removes the backslash.

- 138,973
It is not awk
that is doing this. It is the shell. !
is a special character in the shell.
What to do
Always quote your arguments. e.g.
awk -F'!'

- 27,993
-
-
4@Kalpesh that's not what's written here in the answer. Look again - at the quotes being used – Chris Davies Mar 11 '20 at 08:35
-
Linux is very, /very/ particular about which quotes you use where: Single quotes ( ' ) are the most protective and anything entered within them will be treated as a fixed literal.
Double-quotes ( " ) allow Expansion to happen, including the history expansion that you're falling foul of.
Backticks ( ` ) execute the command between them, allowing you to assign the result to a variable (although bash also provides the more sensible "$(" and ")" delimiters for this). – Phill W. Mar 11 '20 at 16:35 -
1@PhillW. It's not Linux, it's bash. Different shells and languages have different quoting rules. – jcaron Mar 11 '20 at 16:41
-
@PhilW Nice comment, but you are falling for the error of mistaking Linux and Gnu/Linux. Linux cares not about quotes. It is just a kernel, and knows nothing about them. Gnu is the other part of the OS, that lives in user space. It includes the shell (
bash
). – ctrl-alt-delor Mar 11 '20 at 17:16
!
has special meaning forbash
when it's not quoted in single quotes. – Shawn Mar 11 '20 at 07:59awk -F! {something}
? What version of Bash is that? (echo $BASH_VERSION
) The exclamation point is the special character for history expansion, but it should only do something if there's anything after it, which there isn't in-F!
. – ilkkachu Mar 11 '20 at 08:15