-2

Consider the following awk statement which sums the values of column 1 in a file

cat $1 e | awk '      {total=total+$1}   # this comment does not contain any single quote marks
                   END {printf("%.2f\n",total)}
               '

It works as expected.

Now let's keep the same statement, but change the comment to have a single quote mark inside

cat $1 e | awk '      {total=total+$1}   # don't do this 
                   END {printf("%.2f\n",total)}
               '

When I run this in either Mac Os or Centos, I get the following error

./bad_sum: line 2: syntax error near unexpected token `
./bad_sum: line 2: `                  END {printf("%.2f\n",total)}'

It looks like awk is trying to match the quote mark in don't with the quote mark after awk and thus gets confused. But since comments are supposed to be ignored, how can this be explained?

Ed Morton
  • 31,617

2 Answers2

4

This has nothing to do with awk. You cannot include a single quote inside a single quote delimited script or string in most shells (the ones considered Bourne-like or csh-like). Try echo 'foo'bar' and see it fail. Now try echo 'foo\'bar' and see it also fail. Now try echo "foo'bar" and echo 'foo'\''bar' and see if you can figure out why they succeed (and no, I'm am not suggesting you wrap scripts in double quotes). See https://mywiki.wooledge.org/Quotes for more info.

Ed Morton
  • 31,617
  • 3
    The in any shell part is not true. You can do echo 'foo''bar' in rc, es, akanga or zsh -o rcquotes. You can do echo 'foo\'bar' in fish. echo "foo'bar" or echo 'foo'\''bar' would not work in rc or akanga. – Stéphane Chazelas May 10 '20 at 15:06
  • @StéphaneChazelas Thanks for the info, I've never had to use rc, fish, or zsh. What's the best way to group the shells that don't allow it - Bourne-compatible or something else? Or is it just random? – Ed Morton May 10 '20 at 15:18
  • 1
    zsh, bash, ksh are Bourne-like, but not Bourne-compatible. What you state is true for Bourne-like (the rc_quotes option is not on by default in zsh) and csh-like shells (two distinct families even if ksh, bash, zsh have many features of csh). See also How to use a special character as a normal one? – Stéphane Chazelas May 10 '20 at 15:27
  • I've updated my answer to say that now, thanks. – Ed Morton May 10 '20 at 15:28
2

It’s because your shell is interpreting the quotes and is interpreting the rest of the awk statement in the shell and not in awk.

jsbillings
  • 24,406
  • Essentially, the first ' takes precedence, and therefore quotes the #. The truncated awk program is perfectly valid -- one action and a comment ending in "dont" (because the t is contiguous with the quoted part). It even gets filenames "do" and "this". On Linux bash, awk fails because it can't open a file "do", before bash fails because of the unbalanced quote. – Paul_Pedant May 10 '20 at 13:35